要使线程安全、快速、可靠的停下来并非易事,java并未提供机制保证线程安全的停止,但是我们可以通过使用中断来完成线程的停止和关闭;
本章节只总结基础线程的取消和关闭,类似封装库提供的方法如Future、线程池不在本章节讨论。
1、interrupted方法
Thread提供了中断相关的方法,这里需要注意的一点是,使用静态的interrupted方法,会清除线程的中断状态。
2、利用volatile变量作为标记,实现线程的关闭,前提是当前线程调用BlockingQ的produce方法,不会进入等待状态。
public class Producer implements Runnable {
private volatile boolean canceled = false; private BlockingQ blockingQ; public Producer(BlockingQ blockingQ) { this.blockingQ = blockingQ; } @Override public void run() { while (!canceled) { blockingQ.produce(); } } public void cancel() { this.canceled = true; }}
3、使用中断方法,实现线程终止或者关闭
上述方法在一定场景下可以保证线程安全的终止,但是对于处于等待状态下的线程,上述方法是不生效的,因为当前线程无法重新检查取消标记
此时需要使用Thread类的中断方法,实现一个更为健壮的线程取消方法,通常,阻塞方法object.wait(), Thread.sleep(), Thread.join()都会检查
线程中断状态,如果处于中断状态,会清除中断状态,并抛出InterruptedException异常,此时线程并未被真正的中断
下面的代码不会正常的关闭线程:由于清除了中断状态并在代码中捕获了该异常;外层判断中断状态时,线程一直执行;
正确的方法是在外层捕获异常
public void produce() { Integer value = new Random().nextInt(); synchronized (lock) { while (this.valueList.size() >= MAX_SIZE) { System.out.println("Thread " + Thread.currentThread().getName() + " produce wait."); try { lock.wait(); } catch (InterruptedException e) { System.out.println("Thread " + Thread.currentThread().getName() + " Produce interrupted!!"); System.out.println(Thread.currentThread().isInterrupted()); } } System.out.println("Thread " + Thread.currentThread().getName() + " produce value."); this.valueList.add(value); lock.notifyAll(); } }
public class Producer implements Runnable { private BlockingQ blockingQ; public Producer(BlockingQ blockingQ) { this.blockingQ = blockingQ; } @Override public void run() { System.out.println(Thread.currentThread().getName()); while (!Thread.currentThread().isInterrupted()) { blockingQ.produce(); } } }
错误的执行结果:
正确示例:
public void produce() throws InterruptedException { Integer value = new Random().nextInt(); synchronized (lock) { while (this.valueList.size() >= MAX_SIZE) { System.out.println("Thread " + Thread.currentThread().getName() + " produce wait."); lock.wait(); } System.out.println("Thread " + Thread.currentThread().getName() + " produce value."); this.valueList.add(value); lock.notifyAll(); } }
public class Producer implements Runnable { private BlockingQ blockingQ; public Producer(BlockingQ blockingQ) { this.blockingQ = blockingQ; } @Override public void run() { try { while (!Thread.currentThread().isInterrupted()) { blockingQ.produce(); } } catch (InterruptedException ex) { System.out.println(Thread.currentThread().getName() + " interrupted!!"); } } }
正确的执行结果:
原文地址:https://www.cnblogs.com/sniffs/p/11624179.html
时间: 2024-10-15 08:29:50