Java 关闭时了解关闭请求标志
我正在阅读B.Goetz JCIP,在第7.2节中遇到了一些关于基于线程的服务的误解。代码如下:Java 关闭时了解关闭请求标志,java,multithreading,queue,Java,Multithreading,Queue,我正在阅读B.Goetz JCIP,在第7.2节中遇到了一些关于基于线程的服务的误解。代码如下: public class LogWriter{ private final BlockingQueue<String> queue; private final LoggerThread logger; public LogWriter(Writer writer){ this.queue = new LinkedBlockingQueue<String
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();
}
}
}
现在他说
log的实现比act sequnce更简单:生产者可以
请注意,服务尚未关闭,但仍在排队
关闭后的消息,再次,生产者有风险
可能在日志中被阻止,并且永远不会解锁
这个问题我不清楚
如果使用者将队列排到某个集合,则会使log()
中被阻止的任何生产者解锁。即使某些生产者试图将日志消息放入队列,它也不会被阻止。我看到的唯一一件事是,由于队列已耗尽,因此不会记录此消息
问题:他为什么说制作人应该被封锁,永远不能解锁。我错过了什么?如果您查看
阻塞队列
文档,您可以看到:
另外支持等待队列的操作的队列
若要在检索元素时变为非空,并等待空格变为空
存储元素时在队列中可用
也就是说,如果队列中没有更多空间,生产者可能会被阻止:如果服务已关闭,队列将不再耗尽。由于代码不完整,很难说出作者的意图。记录器线程可能还会检查
shutdownRequested
以停止日志记录:
public void run() {
try{
while(shutdownRequested)
writer.println(queue.take());
} catch(InterruptedException ignored){
} finally {
writer.close();
}
}
如果你写这个,考虑一个场景,当队列满了,并且在“代码>队列中有线程被阻塞时,请停止。放进< /COD>”:日志线程停止调用<代码>队列。p>
即使情况并非如此,变量
shutdownRequested
也存在竞争条件。线程可能会在读取变量和消息在log
方法中排队之间请求关闭,因此请求关闭后消息仍会排队。您能发布完整的代码吗?shutdownsrequested
是否仅在log
方法中使用,或者也在记录器线程中使用?@Joni这是完整的。他没有提供更多详细信息。@Joni logger线程是一个内部类,但当请求关闭时,我们只需将标志设置为true
,然后使用者清空队列。因此,所有在log()
中哭泣的记录器都将解锁。唯一可能发生的情况是,大于队列容量的线程数会重现这种竞争条件……我同意,这应该只适用于多线程和samll容量的情况。但仍然有可能。
public void run() {
try{
while(shutdownRequested)
writer.println(queue.take());
} catch(InterruptedException ignored){
} finally {
writer.close();
}
}