1 进程、线程、管程

1.1 进程

  我们在电脑上打开微信就开启了一个进程,打开一个腾讯视频又是一个进程。

 

1.2 线程

  一个进程中可以有一个和多个线程。进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存,从而极大地提高了程序的运行效率。多个线程执行进程中的不同的任务。

  比如qq,我发送文件给一个朋友是一个线程,同时我在浏览qq空间又是一个线程。

 

1.3 管程

  在多线程中我们通常会用到锁来保证同步。JAVA支持方法级和方法内的同步,都是通过管程来实现的。

 

2 用户线程和守护线程

2.1 示例1

  通过Thread的isDaemon可以判断是否为守护线程


public
class Test001 { public static void main(String[] args) { Thread t = new Thread(()->{ System.out.println("创建的线程执行"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("创建的线程执行结束"); },"t线程"); System.out.println(t.getName() + "是否是守护线程:" + t.isDaemon()); t.start(); System.out.println(Thread.currentThread().getName() + "是否是守护线程:" + Thread.currentThread().isDaemon()); System.out.println("主线程执行结束"); } }

执行结果,发现自己创建的线程默认为用户线程,主线程也是用户线程

t线程是否是守护线程:false
main是否是守护线程:false
主线程执行结束
创建的线程执行
创建的线程执行结束

 

2.2 示例2

相较于上面,加了一行代码t.setDaemon(true);设置t为守护线程

public class Test001 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            System.out.println("创建的线程执行");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("创建的线程执行结束");
        },"t线程");
    t.setDaemon(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">);
    System.</span><span style="color: #0000ff;">out</span>.println(t.getName() + <span style="color: #800000;">"</span><span style="color: #800000;">是否是守护线程:</span><span style="color: #800000;">"</span> +<span style="color: #000000;"> t.isDaemon());
    t.start();
    System.</span><span style="color: #0000ff;">out</span>.println(Thread.currentThread().getName() + <span style="color: #800000;">"</span><span style="color: #800000;">是否是守护线程:</span><span style="color: #800000;">"</span> +<span style="color: #000000;"> Thread.currentThread().isDaemon());
    System.</span><span style="color: #0000ff;">out</span>.println(<span style="color: #800000;">"</span><span style="color: #800000;">主线程执行结束</span><span style="color: #800000;">"</span><span style="color: #000000;">);
}

}

执行结果,t变成了守护线程。

而且发现"创建的线程执行结束"这一行文字没有打印,也就是说Thread.sleep(2000);后面的代码没有执行。

因为用户线程执行完成后,不管守护线程有没有执行完成,都会直接结束。

t线程是否是守护线程:true
main是否是守护线程:false
主线程执行结束
创建的线程执行

 

2.3 小结

  1)自己创建的线程默认是用户线程

  2)可以通过isDaemon判断线程是否为用户线程

  3)可以通过setDaemon设置为守护线程或者用户线程

 

3 线程的状态

3.1 状态迁移图

 

 

3.2 join方法

  正在运行的线程,把另外一个线程加入到本线程的运行,等这个线程运行完后,继续运行,通常用来等待一个线程的完成。
  在t1调t2的join方法,t1进入wait状态,t2变为runnable状态,t2执行完,t1变为runnable状态继续执行