gpt4 book ai didi

java - 如何使用正确的 run() 方法实现来保持 CopyOnWriteArrayList 的线程安全?

转载 作者:行者123 更新时间:2023-12-01 17:01:11 24 4
gpt4 key购买 nike

我正在使用 ExecutorServicefixedThreadPool。我通过实现 Runnable 接口(interface)来创建线程。在 run() 方法中,我调用一个耗时的函数(现在假设为 Thread.sleep()),最后将一个元素添加到线程安全 CopyOnWriteArrayList。我正在 for 循环中提交线程。在 for 循环结束时,我关闭 ExecutorService 并等待终止。

但是,列表中元素的数量与循环迭代的数量并不相同。我的并发思维错误在哪里?

以下是此问题的代码示例:

public class TestProgram {

public static void main(String[] args) throws Exception {

ExecutorService executor = Executors.newFixedThreadPool(4);
CopyOnWriteArrayList<String> stringList = new CopyOnWriteArrayList<String>();

for (int i = 0; i < 1000; i++) {
executor.submit(new myThread(stringList));
}

executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
System.out.println(Integer.toString(stringList.size()));

}
}

class myThread implements Runnable {

CopyOnWriteArrayList<String> stringList;

public myThread(CopyOnWriteArrayList<String> stringList) {
this.stringList = stringList;
}

public void run() {
String string = new String("test");

try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(myThread.class.getName()).log(Level.SEVERE, null, ex);
}
stringList.add(string);

}
}

最佳答案

您只是没有给它足够的时间来完成。如果您想串行执行此操作,则需要 1000 * 100 毫秒,即 100 秒。您正在使用四个线程运行它,因此除以 4 即可得到 25 秒。您只需等待 10 秒即可完成。为了安全起见,将其增加到 26 秒,您应该会看到结果。

ExecutorService#awaitTermination 将等待 N 秒来完成,如果没有完成,它将简单地返回并继续执行。为了证明我的观点,请检查返回值System.out.println(executor.awaitTermination(10, TimeUnit.SECONDS));

这里更好的解决方案是使用new CountDownLatch(1000),将每个可运行任务添加到列表后countDown,最后让主线程等待完成。

关于java - 如何使用正确的 run() 方法实现来保持 CopyOnWriteArrayList 的线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27570122/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com