停止线程
程序员文章站
2022-03-04 18:34:58
预备知识 interrupt() Thread的非静态方法,标记当前线程的中断状态为true; isInterrupted() Thread的非静态方法,查看当前线程的中断状态; interrupted() Thread的静态方法,查看当前线程的中断状态,并清除(将状态改为false); 如果当前线 ......
预备知识
- interrupt() Thread的非静态方法,标记当前线程的中断状态为true;
- isInterrupted() Thread的非静态方法,查看当前线程的中断状态;
- interrupted() Thread的静态方法,查看当前线程的中断状态,并清除(将状态改为false);
- 如果当前线程设置了中断,然后调用sleep()/wait()/join()或者当前线程处于sleep()/wait()/join()然后中断该线程会抛出InterruptException,并且会清除中断状态。
- volatile 修饰变量,使得被修饰的变量修改以后引起其他线程工作内存中对此变量的缓存无效,进而保持可见性。
停止线程
1. 通过轮询线程的中断状态
- 通过设置中断状态,进而通过轮询中断状态决定是否停止。
public class ThreadDemo implements Runnable { @Override public void run() { // 轮询中断状态 while (Thread.currentThread().isInterrupted()) { doSomething(); } } }
- 如果在while里面使用了sleep()/wait()/join(),此时如果通过设置线程中断状态停止线程,会抛出InterruptException,会清除中断状态,导致不会正常停止,所以需要重新设置线程中断状态。
public class ThreadDemo implements Runnable { @Override public void run() { while (!Thread.currentThread().isInterrupted()) { doFirstPartOfIncrement(); try { Thread.sleep(1000); } catch (InterruptedException e) { // 抛出了InterruptException,此时会清除当前线程的中断状态,需要重新设置中断状态,保证线程正常终止 Thread.currentThread().interrupt(); } } } }
2. 通过轮询共享变量
- 通过设置共享变量,进而通过轮询共享变量决定是否停止。
public class ThreadDemo implements Runnable { // 状态变量 private volatile boolean stop = false; public void stop() { stop = true; } @Override public void run() { // 轮询状态变量 while (!stop) { doSomething(); } } }
3. 通过Thread.stop()
-
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
会将此线程获取的Monitor对象(也就是常说的通过synchronized获取的锁)释放。比如一个线程负责维护一个对象Product中的两个变量saleCount和StockCount处于saleCount <= stockCount状态,当某个时刻saleCount > stockCount,同时此线程被stop()强制停止,会导致逻辑错误。
参考
下一篇: Go指南练习_斐波纳契闭包