Летучий ли гарантия безопасности ниток? Этот пример ArrayList
У меня есть ArrayList 'X', который передается нескольким потокам, где каждый поток добавляет больше данных в этот ArrayList 'X', используя addAll(). Очевидно, что здесь есть проблемы с многопоточностью, одним из вариантов было бы сделать так, чтобы часть addAll () кода "синхронизировалась" (или) использовала copyOnWriteArrayList.
Но мой вопрос здесь заключается в том, будет ли объявление ArrayList 'volatile' достигать той же цели? Упорядочивает ли JVM эти инструкции по чтению / записи и предотвращает проблемы многопоточности?
2 ответа
Будет ли объявление ArrayList 'volatile' достичь той же цели?
Вы не можете на самом деле. Когда ты пишешь
volatile ArrayList list;
это делает list
ссылка volatile, а не базовый ArrayList. Это также означает, что когда вы делаете
list.add(x);
list
читается, поэтому вы получаете только барьер чтения, а не барьер записи.
ПРИМЕЧАНИЕ. Это не делает операцию атомарной, а это то, что вам действительно нужно, но без барьера записи вы можете даже не увидеть эту операцию в другом потоке.
Упорядочивает ли JVM эти инструкции по чтению / записи и предотвращает проблемы многопоточности?
Это упорядочит чтение соответственно, но не таким образом, который может использоваться, чтобы избежать многопоточных проблем в этом случае. т. е. нет способа сделать эту работу нестабильной, не говоря уже о том, что JVM будет делать то, что вы хотите, не беспокоясь об этом.
synchronized
для сравнения можно использовать правильно. Вы все еще можете ошибиться, это не доказательство, но у вас есть хороший шанс сделать все правильно.
Нет, изменчивый не будет работать здесь. Ключевое слово Volatile гарантирует, что каждая операция чтения всегда получит последнее обновленное значение. Здесь вам нужно использовать синхронизированный.