线程的启动与终止:
1.start与run的区别
通过start来启动线程,会进行大量的初始化线程的操作,并且执行在 run()方法里的代码。但是如果你直接调用 run()方法,它不会创建新的线程也不会执行调用线程的代码,只会把 run 方法当作普通方法去执行。
2.线程的终止
线程执行完(执行完run()并退出) - 自然终止
异常终止(抛出为处理的异常)
被强制终止 - stop已废除 ---原因:stop方法不安全,会破坏对象。
请求中断线程 -- interrupt() //设置线程的中断状态设置为true
和isInterrupt()//线程允许自己中断自己,所以可以用这个方法在任务中检测线程的中断状态,对中断做处理
Thread下的static interrupted() --与isInterrupt()返回结果相同,但是会清楚线程的中断状态
当interrupt方法中断阻塞的线程的时候,线程会抛出一个异常并且清除中断状态,如果我们想要打断阻塞状态,我们可以捕获异常后重新设置中断状态并且配合isInterrupt()打断阻塞的状态
守护线程与用户线程的区别
创建方式 守护线程需要setDaemon(true)
守护线程的设置必须在启动之前,否则会报运行时错误
守护线程随着主线程的退出而退出,用户线程则是随着线程任务的完成而推出
常见的守护线程 垃圾回收线程finalizer、信号控制器 给JVM发信号、监听Ctrl+C的守护线程、引用处理线程(用来处理引用队列)
什么是线程组?为什么在java中不推荐使用线程组
Java中的线程组是一个ThreadGroup类对象,它充当了一个父容器,可以将同一类线程分成一组,并提供追踪这些线程状态、批量设置优先级,批量异常处理。
必须先有线程组,然后在创建线程的时候利用构造方法绑定线程组,JVM不允许线程更改线【程组,线程组的拓展复杂,功能有限,有更好的替代
Yield方法的作用:让出当前线程的CPU执行权,从新进入调度队列中竞争执行权
防止单个线程霸占CPU资源
Yield方法和sleep方法为什么是静态方法
Yield是让当前线程让出当前时间片的CUP控制权,Sleep是让当前线程任务阻塞知道睡眠时间结束,两个都是让正在运行的线程暂时停止执行线程任务。
所以其他处于等待的线程调用这些方法是没有意义的,所以是静态方法,他们可以在当前正在运行的线程中执行,避免我们错误认识认为任何时候都可以调用yield和sleep。
Join方法的底层原理:
Join是为了实现调用线程插队,知道线程退出或者到达设置的时间,才会让主线程停止阻塞;Join底层会不断检测调动线程的isAlive,如果alive就调用主线程的wait方法,这样子不断自旋,直到调用join的线程完成线程任务退出的时候,会设置自己的状态为Terminated,是的IsAlive返回false,并且通过notifyAll方法通知主线程重新执行,重新竞争CPU。
while(isAlive){
wait(0);
}重点:join用过wait方法配合自旋让主线程一直等待,通过notifyAll通知主线程恢复运行。
原文:https://juejin.cn/post/7385419589021581349