Основная проблема (и), с которой мы сталкиваемся в многопоточном коде, - это совместное использование данных, и я согласен с этим с целью параллелизации параллелизма, и это происходит "в основном", когда во время параллелизированной обработки потокам требуется доступ для чтения / записи на общем ресурсе.data.
Ключевое слово java synchronized разрешает следующее:
Указывает JVM установить блокировку на мониторе объекта или части синхронизированного кода, что дает ему эксклюзивный доступ кэта часть кода или объекта.
Вот пример синглтона:
public class Singleton {
private Singleton INSTANCE;
private Singleton() {
}
public Singleton getInstance() {
if (null == INSTANCE) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Этот синглтон не потокобезопасен , если поток пытается получитьэкземпляр, в то время как другой также пытается сделать то же самое (условие гонки), может случиться так, что до того, как поток номер один завершит создание экземпляра, второй уже имел доступ к методу getInstance()
и создал свой собственный экземпляр SingletonЭто означает, что в момент времени T у нас должно быть два экземпляра синглтона (называемыйt).
Чтобы решить эту проблему, нам нужно синхронизировать творческое поведение синглтона, это можно сделать с помощью ключевого слова synchronized
над оператором if на самом INSTANCE
:
public class Singleton {
private Singleton INSTANCE;
private Singleton() {
}
public Singleton getInstance() {
synchronized (Singleton.class) {
if (null == INSTANCE) {
synchronized(Singleton.class) {
Singleton inst = new Singleton();
INSTANCE = inst;
}
}
}
return INSTANCE;
}
}
В результате, когда первый поток запрашивает экземпляр Singleton, а во время создания JVM устанавливает блокировку на монитор INSTANCE, запрещая любой доступ к INSTANCE до тех пор, пока один поток не завершит свой запрос.
Существуют и другие способы достижения этого, цитированная выше книга является отличным источником обучения, а также Javadoc.