java - 并发检查栈是否为空

标签 java multithreading

如何确保在后续调用 !stack.isEmpty()stack.pop() 之间,堆栈不会被不同的线程访问?

executor.submit(()->{
    File currentDirectory;
    while(!directoryToSearch.isEmpty()) {
        currentDirectory = directoryToSearch.pop(); 
        ....
    }
}

换行:

while ((currentDirectory = directoryToSearch.pop()) != null)

在 try 和 catch block 中或为已同步的数据结构创建锁根本感觉不是一个好的解决方案。

堆栈在释放 n 个线程之前已被填满,并且不会再次被填满。我看到的问题是,在最后一个对象上,多个线程可能会在其中一个线程能够弹出一个元素之前通过 stack.isEmpty() 检查,从而导致所有其他线程出现异常。

最佳答案

我建议使用ConcurrentLinkedQueue。它应该比同步和面向 future 更快(如果您后来决定在线程中添加项目,而您将它们拉出,那么它就会起作用)。

第二个选择:只捕获异常并继续,就像堆栈为空一样。

这比 Synchronized 更快,因为每当您进入同步块(synchronized block)时,synchronized 都会产生相当严重的惩罚,但异常只会在遇到异常时才会导致速度问题(这种情况只会发生在没有执行任何有趣操作的线程上)。

异常可能比 ConcurrentLinkedQueue 快一点,但也只是一点点。

关于java - 并发检查栈是否为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47638711/

相关文章:

c# - 具有无限循环和 thread.sleep 高 CPU 使用率的多线程

java - 如何在不使用 System.exit(0) 的情况下停止回溯?

java - 将函数应用于按流分组的嵌套列表

java - 将 ElasticSearch 与 Spring Data 结合使用时自动生成数字 id

javascript - 是什么阻止 HtmlUnit 加载 PSN 商店页面?

java - 如何在我的 Java 代码中使用多线程/并发

multithreading - std::this_thread::yield()用法?

java - 这个简单的服务器-客户端程序不会发送/接收除初始确认之外的数据。为什么?

java - 有条件需要 a4j 形式的 jsf 验证

java - Java中的阻塞队列