我可以使用Collection.size()替换此代码中的计数器吗?

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.

我对吗?

dje*_*lin 5

不,这实际上会造成僵局.

您将需要同步puttake如果你想使用size并行方式.但是take阻塞,你现在可以take在与put调用相同的对象上同步阻塞调用.take什么都不能采取put.放弃锁put之前不能放take.那是一个僵局.