多线程的小结

进程线程的概念

进程是建立在操作系统的一次运行活动,是系统进行资源分配调度的基本单位,可理解为一个一个的程序。线程是一次指令的顺序执行,是系统独立分配CPU的基本单位,可理解为进程中独立运行的子任务。

为什么引入多线程

同步单线程环境下,使得不相关、相互独立的任务之间需要排队等候CPU,使得CPU的利用率低下,异步引入多线程使得不同的任务能在CPU自如地切换,提高了CPU的利用率。

线程实现方式

实现Runnable接口和继承Thread,并实现run()方法(一般使用Runnable接口实现,原因:接口能够实现多继承,类只能单继承)。

:在主函数中多次调用start()会出现Exception in thread "main" java.lang.IllegalThreadStateException
多线程环境下,在主函数直接调用Thread.run()方法而非调用Thread.start(),则实现的是同步效果,而非异步执行

线程方法

线程生命周期交互图

isAlive():测试线程是否处于活跃状态。
getId():线程的唯一标识号。
yield():放弃当前CPU让其他任务占用CPU,但放弃时间不确定。有可能刚放弃又占用。
sleep()/interrupt,wait()/notify notifyAll:
调用sleep()方法不会释放锁(不让出系统资源),而wait方法释放了锁(进入线程等待池等待,让出系统资源)使得其他线程可以使用同步控制块或者方法,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行终止。
suspend/resume:
如果使用不当, 极易造成公共的同步对象的独占, 使得其他的线程无法访问公共的同步对象。

public class ThreadSuspendTest {
    public synchronized void printString(){
        System.out.println("begin");
        if(Thread.currentThread().getName().equals("a")){
            System.out.println("Thread a will suspend");
            Thread.currentThread().suspend();
        }
        System.out.println("end");
    }
    public static void main(String[] args){
        try{
            final ThreadSuspendTest threadSuspendTest = new ThreadSuspendTest();
            Thread thread1 = new Thread(new Runnable() {
                public void run() {
                    threadSuspendTest.printString();
                }
            });
            thread1.setName("a");
            thread1.start();
            Thread thread2 = new Thread(new Runnable() {
                public void run() {
                    System.out.println("B线程启动了, 但是无法进入printString方法中");
                    System.out.println("因为printString()方法陪线程a锁定并且永远suspend暂停了");
                    threadSuspendTest.printString();
                }
            });
            thread2.setName("B");
            thread2.start();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
/*begin
Thread a will suspend
B线程启动了, 但是无法进入printString方法中
因为printString()方法陪线程a锁定并且永远suspend暂停了*/

停止线程的方法

ThreadDeath

实例变量的安全问题

  • (1)实例变量


  • (2)同一实例访问static时发生线程安全问题
  • (3)system.out.println(i++);与i++/i--..联合使用异常

this.getName与currentThread().getName()区别

class CountOperate extends Thread {
    public CountOperate() {
        System.out.println("CountOperate---begin");
        System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());
        System.out.println("this.getName()=" + this.getName());
        System.out.println("CountOperate---end");
    }
    @Override
    public void run() {
        System.out.println("run---begin");
        System.out.println("Thread.currentThread().getName()=" + Thread.currentThread().getName());
        System.out.println("this.getName()=" + this.getName());
        System.out.println("run---end");
    }
}
public class Run3_getName {
    public static void main(String[] args) {
        CountOperate c = new CountOperate();
        Thread t1 = new Thread(c);
        t1.setName("A");
        t1.start();
    }
}

输出:
CountOperate---begin
Thread.currentThread().getName()=main
this.getName()=Thread-0
CountOperate---end
run---begin
Thread.currentThread().getName()=A
this.getName()=Thread-0
run---end

守护线程

守护线程
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 进程和线程 进程 所有运行中的任务通常对应一个进程,当一个程序进入内存运行时,即变成一个进程.进程是处于运行过程中...
    胜浩_ae28阅读 5,170评论 0 23
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。在这之前...
    4ea0af17fd67阅读 597评论 2 17
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 3,007评论 1 18
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,515评论 1 15
  • 听了腿姐的课,开始慢慢地理解为什么那么多人崇拜毛泽东了,以前是我以自己的固有经验思维去理解万物。像腿姐说的我们中国...
    王丽q阅读 15评论 0 0