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'; в противном случае возможно, что это не будет делать то, что вы хотите. –
@DavidWallace Чтобы быть понятным, ключевое слово 'volatile' используется, чтобы указать, что значение переменной будет изменено различными потоками. Создание переменной 'volatile' не влияет на то, можно ли считать код« потокобезопасным ». –
Это не потокобезопасность, потому что, когда у вас есть несколько потоков, у вас будет 'ConcurrentModificationException' на' mainList.add (r.nextInt (200)) '. –