线程的生命周期
1.新建:
当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
Thread thread = new Thread();
2.就绪
线程已经被启动,并不代表run()方法就被立即执行。这时正在等待被分配给CPU,也就是说此时线程正在就绪队列中等候得到CPU资源。
thread.start();
3.运行
线程获得CPU资源正在执行任务执行run()方法,此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到死亡。
run()
4.阻塞
由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。
正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。
正在等待:调用wait()方法。(调用motify()方法回到就绪状态)
5.死亡
当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
自然终止:正常运行run()方法后终止
异常终止:调用stop()方法让一个线程终止运行
结合现实理解线程:
你成为一个肥天高中的高中生(new)。
三年努力你准备高考(Runable执行是start()方法),高考你和其他人竞争(抢占CPU)。
竞争成功了你就升入肥天大学,过大学生活(running,执行run()方法)。
正常情况下你会顺利毕业(正常退出:run()方法结束)
不正常情况1:你重修(yield) ,让出大学名额(让出 CPU 资源),进入Runnable状态
不正常状况2:对学校不满意退学了(wait()),在家等待(motify()后)重整旗鼓,进入就绪状态(Runnable)。
不正常情况3:你病了,一直昏迷(sleep())退学了,醒来就继续参加高考(Runnable)
不正常情况4:自己辍学了(异常退出:stop())。
阻塞状态和等待状态
实际上不用可以区分两者, 因为两者都会暂停线程的执行. 两者的区别是: 进入waiting状态是线程主动的, 而进入blocked状态是被动的. 更进一步的说, 进入blocked状态是在同步(synchronized)代码之外, 而进入waiting状态是在同步代码之内.(摘自csdn论坛中很好解答)
sleep()和wait方法的区别:
1.wait()是object的方法,sleep()是Thread的静态方法。
2.wait()等待时是不持有锁的,sleep()睡眠时是持有锁的
3.wait()不需要捕获异常,sleep()需要捕获异常
4.wait()必须在同步代码块或同步方法中,sleep()可以再任何地方
join():
原来主线程和子线程是并行的关系,但是一旦主线程使用了子线程的join()方法,就会变成串行的关系。主线程停止运行,等子线程执行完毕之后,主线程才会开始执行。
线程在死亡的时候会自动调用自身的notifyAll方法,来释放所有的资源和锁。
注意:那个线程调用了x.join()方法,那个线程就会被挂起,join()并不影响同一时刻处在运行状态的其他线程。
join()部分原文链接:https://blog.csdn.net/qq_33236248/article/details/80266487
join()部分原文链接:https://blog.csdn.net/u013425438/article/details/80205693