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状态继续执行