Java 我可以使用Collection.size()替换此代码中的计数器吗?
代码如下:Java 我可以使用Collection.size()替换此代码中的计数器吗?,java,multithreading,concurrency,Java,Multithreading,Concurrency,代码如下: public class LogService { private final BlockingQueue<String> queue; private final LoggerThread loggerThread; private final PrintWriter writer; @GuardedBy("this") private boolean isShutdown; @GuardedBy("this") private
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();
}
}
}
}
公共类日志服务{
私有最终阻塞队列;
专用最终LoggerThread LoggerThread;
私人最终印刷作家;
@GuardedBy(“此”)私有布尔值设置;
@Guardby(“this”)private int reservations;//No,这实际上会造成死锁
如果您想以并行方式使用size
,则需要同步put
和take
。但是take
是阻塞的,您现在将在与put
调用相同的对象上同步一个阻塞take
调用。take
只有在put
.put
在take
放弃锁定之前无法放入。这是一个死锁。使用“reservations”变量是一个很好的域设计,因为它比大小更有意义,您可以用它来表示域概念,如可用保留的总数等
在性能方面
ArrayBlockingQueue-调用size函数将导致速度变慢,因为它获取了读取大小的锁,这也将减慢take或put操作
LinkedBlockingQueue-调用大小是原子/易失性读取,它有性能成本。队列put
和get
不同步。保留
修改是。我查看了put
和take
方法的源代码,它们似乎与同步de>Lock
@user2916610问题是size
是否也同步。size
也同步。@user2916610我正在查看并放置/使用不同的锁。put
使用Lock
而size
不同步,请将计数器替换为queue.size()
可能会造成竞争条件。但我不知道在什么情况下会出现死锁。