java - 如何根据 boolean 值同步代码?

标签 java concurrency synchronization atomic synchronized

我有这个代码:

    private volatile boolean immortal;
    private Object lock = new Object();
    
    public void set(boolean immortal) {
        this.immortal = immortal;
    }

    public void kill() {
       // .... contains some other code. 
       synchronized(lock) {
            if (!immortal) {
               for (int i = 0; i < numThreads; i++) {
                   runnableList.add(POISON_PILL);
               }
            }
       }
    }

我的用例是,我希望 kill 方法中的 if 语句在 immortal 值更改之前运行完成。有没有更好的方法可以在不锁定对象的情况下执行此操作?

我的意思是,仅当 boolean 变量的值为 false 并且在运行完成之前不允许更改 boolean 值时,同步块(synchronized block)的最佳方法是什么?我可以使用 AtomicBoolean 实现此目的吗?

最佳答案

一个巧妙的方法是将您的 runnableList 声明为同步列表:

// where T is whatever type it needs to be
List<T> runnableList = Collections.synchronizedList(new ArrayList<>());

然后您可以在没有显式同步的情况下添加它:

if (!immortal) {
  runnableList.addAll(Collections.nCopies(numThreads, POISON_PILL));
}

这是有效的,因为对 addAll 的单个调用是原子的。

不过,这并不是在没有同步的情况下实现的,它只是列表内部的。


话虽如此,很难推荐“更好”的解决方案,因为尚不清楚需求是什么。同步(等)用于在多线程操作时保留对象的不变量。

例如,为什么在向 runnableList 添加内容时需要 immortal 保持不变?您还如何访问immortalrunnableList?等等

关于java - 如何根据 boolean 值同步代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64676963/

相关文章:

c - 光泽文件锁定,用于并发访问

javascript - html 和 javascript 中从美元到欧元或任何其他货币的货币转换器

java - JFrame 调用多个并发线程来更新调用者 JFrame 中的 JProgressBar

java - Thread.sleep() 和 Object.sleep() 的区别

java - 如何在现有文件中追加新行?

java - 在java应用程序中实现CSRF时出现错误

c++ - 线程安全编程

java - 在 onDrag 函数中保存坐标时出现问题

javascript - Nodejs - 锁、 key 和 worker - 同步代码和在 javascript 世界中等待

Android 同步适配器资源