use*_*610 8 java concurrency multithreading
这是代码:
public class LogService {
private final BlockingQueue<String> queue;
private final LoggerThread loggerThread;
private final PrintWriter writer;
@GuardedBy("this") private boolean isShutdown;
@GuardedBy("this") private int reservations; // <-- counter
public void start() { loggerThread.start(); }
public void stop() {
synchronized (this) { isShutdown = true; }
loggerThread.interrupt();
}
public void log(String msg) throws InterruptedException {
synchronized (this) {
if (isShutdown)
throw new IllegalStateException(...);
++reservations;
}
queue.put(msg);
}
private class LoggerThread extends Thread {
public void run() {
try {
while (true) {
try {
synchronized (LogService.this) {
if (isShutdown && reservations == 0)
break;
}
String msg = queue.take();
synchronized (LogService.this) {
--reservations;
}
writer.println(msg);
} catch (InterruptedException e) { /* retry */ }
}
} finally {
writer.close();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是Java Concurrency in Practice一书中的一个片段,我正在考虑可能计数器reservations是不必要的,因为我们可以简单地queue.size()用来获取元素的数量queue.
我对吗?
不,这实际上会造成僵局.
您将需要同步put和take如果你想使用size并行方式.但是take阻塞,你现在可以take在与put调用相同的对象上同步阻塞调用.take什么都不能采取put.放弃锁put之前不能放take.那是一个僵局.