Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我可以使用Collection.size()替换此代码中的计数器吗?_Java_Multithreading_Concurrency - Fatal编程技术网

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()
可能会造成竞争条件。但我不知道在什么情况下会出现死锁。