停止基于线程的服务
摘自JAVA并发编程实战
与其他封装对象一样,线程的所有权是不可传递的:应用程序可以拥有服务,服务也可以拥有工作线程,但是应用程序不能拥有工作线程,因此应用程序不能直接停止工作线程。
JAVA并发编程实战第七章前面介绍的主要是单个线程的中断,而停止基于线程的服务是针对于多个线程来说的。一个服务中可能有多个线程,这些线程之间是有一定关系的,如何安全的停止这些线程是我们需要考虑的。
本次做了一个关于安全的关闭生产者-消费者服务的小例子。将创建一个生产者-消费者服务:ProduceConsumerService 。这个服务中有若干个生产者线程Product和若干个消费者线程Consumer。应用程序为一个test函数,运行ProduceConsumerService服务。并且ProduceConsumerService服务提供安全的取消方法。
对于生产者-消费者所谓的安全的取消是指:需要同时取消生产者和消费者线程;并且消费者应当处理完已经生产了的消息后再关闭;生产者已经生产了的消息,但是因BlockingQueue队列已满而阻塞,依然需要等待队列有空位后提交,然后再关闭。
先创建生产者-消费者服务
Product生产者
每隔1s生产一个数,放入BlockingQueue中
因为循环调用了BlockingQueue的put函数,所以可以识别中断信号并抛出InterruptedException异常,直接结束线程执行。
public class Produce extends Thread {
private BlockingQueue<String> deque;
private String name;
private Integer i;
private boolean Isshutdown;
public Produce(BlockingQueue deque, String name){
this.deque = deque;
this.name = name; //线程名
i=0; //生产信息
}
@Override
public void run() {
try {
while (true) {
//执行生产操作
System.out.println("生产者" + name + ": 生产了" + i);
deque.put(name+ "+" + i);
// 生产后休眠1s
Thread.sleep(1000);
i++;
}
}catch (InterruptedException e){
}finally {
System.out.println("生产者" + name + "退出");
}
}
}
消费者同理Consumer
public class Consumer extends Thread {
private BlockingQueue<String> deque;
private String name;
private boolean Isshutdown;
public Consumer(BlockingQueue deque