public class TestConcurrentForList {
List<Integer> mainList = new ArrayList<Integer>();
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
Random r = new Random();
public void start() throws InterruptedException {
Runnable cmd = new Runnable() {
@Override
public void run() {
List<Integer> tempList = mainList;
mainList = new ArrayList<Integer>();
for (Integer i: tempList) {
System.out.println("subThread:" + i);
}
}
};
scheduledExecutorService.scheduleAtFixedRate(cmd, 1, 1, TimeUnit.MILLISECONDS);
while (true) {
mainList.add(r.nextInt(200));
Thread.sleep(100);
}
}
public static void main(String[] args) {
TestConcurrentForList tester = new TestConcurrentForList();
try {
tester.start();
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}
}我们的产品代码这段Java代码线程安全吗?
部分喜欢此,主线程和子线程共享mainList。我运行测试时间,但从不重现ConcurrentModificationException。
更新:
感谢您的回答道:这段代码实际上是我们的生产代码的简短抽象。我想要做的事情其实很简单:
主线程拥有一个列表来接收来自某些源的数据,当列表达到一定的大小时主线程将列表传递给存储数据到一个子线程的子线程数据库。
也许更安全做到这一点的方法是提取
List<Integer> tempList = mainList;
mainList = new ArrayList<Integer>();
主线程和templist传递给子线程。我之前列出的代码是遗留代码,我想修复此代码。
你应该明确声明'mainList'是'volatile';否则有可能这不会做你想做的事情。 – 2014-08-30 01:42:47
@DavidWallace要清楚,'volatile'关键字用于表示变量的值将被不同的线程修改。使变量'volatile'不影响代码是否可以被认为是“线程安全的”。 – 2014-08-30 01:52:24
它不是线程安全的,因为当你有多个线程时,你将在'mainList.add(r.nextInt(200))'上产生'ConcurrentModificationException'。 – 2014-08-30 01:59:46