В моем случае проблема была в конфигурации времени выполнения сервера:
Проверьте, что JRE - это необходимая версия:
Проект был в версии 1.7, а сервер JRE был установлен как 1.6, после того, как он перешел к правильной версии Java, которую он начал нормально.
Я предполагаю здесь (извините, если не в базе), что вы ищете случайное число между 0 < = x < 1000:
ThreadLocalRandom.current().nextInt(1000);
Здесь есть две проблемы: Безопасная публикация, а затем последующая безопасность потока для mutate (shuffle()
), за которой следует чтение (get(0)
).
Я не думаю, что ваш кодовый адрес является безопасной публикацией вообще. Для этого используйте volatile
или final
, а для volatile
сделайте назначение последним в ctor.
public class Generator {
private final List<Integer> list = new ArrayList<>();
public Generator() {
for (int i = 0; i < 1000; i++) {
list.add(i);
}
}
Или
public class Generator {
private volatile List<Integer> list;
public Generator() {
List<Integer> temp = = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
temp.add(i);
}
list = temp;
}
Теперь я думаю, что вы можете синхронизироваться с list
(или любым другим объектом), чтобы получить безопасность потока. Вы должны убедиться, что get
находится внутри синхронизированного блока. Обратите внимание, что в вашем коде есть ошибка, и на самом деле он не выдает уникальных чисел.
public Integer generate() {
synchronized( list ) {
Collections.shuffle(list);
return list.get(0);
}
}
Или
public synchronized Integer generate() {
Collections.shuffle(list);
return list.get(0);
}
См. Брайан Гетц Параллелизм Java на практике для получения дополнительной информации, особенно Безопасная публикация. SO также кратко обсуждает шаблон безопасной публикации .
Получение уникальных чисел - это просто логика, не связанная с безопасностью потоков. Сначала перемешайте только один раз в ctor, затем просто увеличьте счетчик, чтобы вернуть числа по порядку. Помните, что в вашем списке только 1000 номеров, поэтому вы можете вернуть не более 1000 уникальных номеров.
private int index;
public synchronized Integer generate() {
if( index >= 1000 ) throw IllegalArgumentError();
return list.get( index++ );
}