线程的生命周期
java线程会创建那么势必也会销毁,所以线程是存在生命周期的。
线程一共有6中状态,NEW \ RUNNABLE \ BLOCKED \WAITING \TIME_WAIRING \TERMINATED
NEW :初始状态,线程被构建,但是还没有调用start方法
RUNNABLED:运行状态,java线程吧操作系统中的就绪和运行两种状态统一称为运行中
BLOCKED 阻塞状态,标示线程进入等待状态,也就是线程因为某一种原因放弃了CPU使用权
阻塞也分为几种情况:
1、等待阻塞:运行的线程执行wait方法,jvm会把当前线程放入=到等待队列
2、同步阻塞:运行的线程在获取对象的同步锁时若同步锁被其他线程占用了 ,那么jvm会把当前的线程放入到锁池中
3、其他阻塞:运行的线程执行Thread.sleep或者join方法或者发出I/O请求时,jvm会把当前线程设置为阻塞状态,处理完成后恢复线程
WAITING:无限等待,需要执行唤醒方法才会回复执行
TIME_WAITING:超时等待,超时以后自动返回,就是定时等待到时间后自动回复
TERMINATED:终止状态,表示当前线程执行完毕
线程的启动和终止
线程调用start方法去启动一个线程,当run方法执行完成后线程的生命周期也就终止了,调用start方法是告诉jvm
启动调用start方法的线程。
线程的终止并不简单。线程的stop方法是不推荐使用的,而且使用它有可能会有不可预料的后果。
调用stop方法会立刻停止run方法中剩余的工作,包括catch或finally中的语句,并抛出ThreadDeath异常,因此可能会导致一些清理性工作得不到完成,如文件,数据库等的关闭
调用stop方法会立即释放该线程所持有的所有锁,导致数据得不到同步。出现数据不一致的问题。
使用interrupt方法设置标志位通知该线程有人希望你停止,而被通知线程是否要停止则由自己决定,被通知线程可以调用isinterrupt方法来查看自己的停止通知标志,默认是false,被通知后是true。
interrupt方法在设置停止标志位时会判断线程是否是阻塞停止的,如果是就会唤醒它来停止,但是这个时候阻塞的线程可能还是无法获取资源继续执行,比如sleep了10秒钟而interrupt执行时只等待了5秒那么该线程就会抛出一个interruptException异常,抛出异常后如果没有主动处理停止线程那么该线程不会停止。
线程复位
被通知中断的线程可以使用interrupted方法来响应外界通知线程的一个停止结果,它标示回复中断标志位false,意思就是说你通知我停止了 但是我不同意我又把自己给救活了,至于我什么终止我自己说了算。
还有一种复位方法就是抛出InterruptedException异常,以毒攻毒,我抛出异常来重置线程停止标志为false。当抛出InterruptedException异常时jvm会先将标志位清除。
join方法
join()方法只会使主线程进入等待池并等待t线程执行完毕后才会被唤醒。并不影响同一时刻处在运行状态的其他线程。
join源码中,只会调用wait方法,并没有在结束时调用notify,这是因为线程在die的时候会自动调用自身的notifyAll方法,来释放所有的资源和锁。