【发布时间】:2016-04-10 18:20:32
【问题描述】:
我正在阅读 B. Goetz JCIP 并在第 7.2 节中遇到了一些关于 cancellin 基于线程的服务的误解。代码如下:
public class LogWriter{
private final BlockingQueue<String> queue;
private final LoggerThread logger;
public LogWriter(Writer writer){
this.queue = new LinkedBlockingQueue<String>(CAPACITY);
this.logger = new LoggerThread(writer);
}
public void start(){ logger.start(); }
public void log(String msg) throws InterruptedException {
queue.put(msg);
}
private class LoggerThread extends Thread {
private final PrintWriter writer;
public void run() {
try{
while(true)
writer.println(queue.take());
} catch(InterruptedException ignored){
} finally {
writer.close();
}
}
}
他说这样的服务没有提供终止它的方法。他给出了另一种选择:
public void log(String msg) throws InterruptedException {
if(!shutdownRequested)
queue.put(msg);
else
throw new IllegalArgumentException("logger is shut down");
}
现在他这么说
日志的实现是 chek-than-act sequnce:生产者可以 观察到服务还没有关闭但是还在排队 关闭后的消息,再次生产者有风险 可能会在日志中被阻止并且永远不会解锁。
强调的内容我不清楚。
如果消费者将队列排空到某个集合,它将使任何在log() 中阻塞的生产者解锁。即使某些生产者尝试将日志消息放入队列,它也不会被阻塞。我看到的唯一一件事是,由于队列已耗尽,因此不会记录此消息。
问题:他为什么说生产者必须被阻止并且永远不能解锁。我错过了什么?
【问题讨论】:
-
你能发布完整的代码吗?
shutdownRequested是仅在log方法中使用,还是在记录器线程中使用? -
@Joni 这就是完整的。他没有提供更多细节。
-
@Joni logger 线程是一个内部类
标签: java multithreading queue