线程的状态及interrupt
https://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247485352&idx=1&sn=175dfedebb2515c075a2f761279ab4ce&chksm=ebd63884dca1b1920b652dae20cda1f2dbcfef00c11671011a0f1587e05e3784a88a38055d91&mpshare=1&scene=1&srcid=0514yZSBFo8l622hi0TJmRic&key=1ffebf935a11638d3eac99db4837924505ff844acd775a7daa06f8239c722818a59a5624f6f1936639df8d47cac8a738b71c2913eee9878c6b0360dfabd0ba92b0f9c8b57c1f53032ed564d2c2f6ca98&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=vzUL0Wl%2BAmaDy8sElICVNpoR9K1k%2BTNUs6WnJljlwO%2FA7ylxk%2BcnB%2BzeNyLoUWiI
总结一下:
1.
线程创建之后调用start()方法开始运行,当调用wait(),join(),LockSupport.lock()方法线程会进入到WAITING状态,而同样的wait(long timeout),sleep(long),join(long),LockSupport.parkNanos(),LockSupport.parkUtil()增加了超时等待的功能,也就是调用这些方法后线程会进入TIMED_WAITING状态,当超时等待时间到达后,线程会切换到Runable的状态,另外当WAITING和TIMED _WAITING状态时可以通过Object.notify(),Object.notifyAll()方法使线程转换到Runable状态。
当线程出现资源竞争时,即等待获取锁的时候,线程会进入到BLOCKED阻塞状态,当线程获取锁时,线程进入到Runable状态。线程运行结束后,线程进入到TERMINATED状态,
响应中断:
操作|状态|方式
no | Runnable | while 循环+isInterrupted
synchoronize | blocked | 无法响应
lock/lockInterruptely | blocked | InterruptedException
wait await | waiting/timed waiting | InterruptedException
2.
中断可以理解为线程的一个标志位,它表示了一个运行中的线程是否被其他线程进行了中断操作。中断好比其他线程对该线程打了一个招呼。其他线程可以调用该线程的interrupt()方法对其进行中断操作,同时该线程可以调用 isInterrupted()来感知其他线程对其自身的中断操作,从而做出响应。
另外,同样可以调用Thread的静态方法 interrupted()对当前线程进行中断操作,该方法会清除中断标志位。需要注意的是,当抛出InterruptedException时候,会清除中断标志位,也就是说在调用isInterrupted会返回false。
一旦抛出InterruptedException,isInterrupted返回false
interrupted是静态方法,返回的是当前线程的中断状态。例如,如果当前线程被中断(没有抛出中断异常,否则中断状态就会被清除),你调用interrupted方法,第一次会返回true。然后,当前线程的中断状态被方法内部清除了。第二次调用时就会返回false。https://www.cnblogs.com/w-wfy/p/6414801.html
书上有个例子
对于isInterrupted(),如果之前调用过thread.interrupt()
,那么它的返回值是true。它的作用就是返回该线程是否有中断标志。多次调用这个方法的结果是一样的。
3.
守护线程在退出的时候并不会执行finnaly块中的代码,所以将释放资源等操作不要放在finnaly块中执行,这种操作是不安全的。
线程可以通过setDaemon(true)的方法将线程设置为守护线程。并且需要注意的是设置守护线程要先于start()方法,否则会报:
Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.setDaemon(Thread.java:1365) at learn.DaemonDemo.main(DaemonDemo.java:19)
这样的异常,但是该线程还是会执行,只不过会当做正常的用户线程执行。