Я знаю, что использование synchronize
ключевого слова перед методом обеспечивает синхронизацию этого объекта. То есть 2 потока, выполняющие один и тот же экземпляр объекта, будут синхронизированы.
Однако, поскольку синхронизация происходит на уровне объекта, 2 потока, выполняющие разные экземпляры объекта, не будут синхронизированы. Если у нас есть статическая переменная в классе Java, вызываемая методом, мы хотели бы, чтобы она синхронизировалась между экземплярами класса. Два экземпляра работают в 2 разных потоках.
Можно ли добиться синхронизации следующим образом?
public class Test
{
private static int count = 0;
private static final Object lock= new Object();
public synchronized void foo()
{
synchronized(lock)
{
count++;
}
}
}
Верно ли, что, поскольку мы определили lock
статический объект и используем ключевое слово synchronized
для этой блокировки, статическая переменная count
теперь синхронизируется между экземплярами класса Test
?
источник
Ответы:
Есть несколько способов синхронизировать доступ к статической переменной.
Используйте синхронизированный статический метод. Это синхронизируется с объектом класса.
Явно синхронизируйте объект класса.
Выполните синхронизацию с другим статическим объектом.
Метод 3 является лучшим во многих случаях, потому что объект блокировки не отображается за пределами вашего класса.
источник
Test.class
и потенциально испортить вам день. Кроме того, инициализация класса выполняется с блокировкой удерживаемого класса, поэтому, если у вас есть сумасшедшие инициализаторы класса, вы можете причинить себе головную боль.volatile
не помогает,count++
потому что это последовательность чтения / изменения / записи. Как отмечено в другом ответе,java.util.concurrent.atomic.AtomicInteger
это, вероятно, правильный выбор.Test.class
.this
будет блокировкой для синхронизированных нестатических методовЕсли вы просто используете счетчик, рассмотрите возможность использования AtomicInteger или другого подходящего класса из пакета java.util.concurrent.atomic:
источник
Да, это правда.
Если вы создадите два экземпляра своего класса
Затем t1.foo и t2.foo синхронизируются с одним и тем же статическим объектом и, следовательно, блокируют друг друга.
источник
Вы можете синхронизировать свой код по классу. Это было бы проще всего.
Надеюсь, вы найдете этот ответ полезным.
источник
Test.class
и влиять на поведение. Вот почему синхронизацияlock
может быть предпочтительнее.Мы также можем использовать ReentrantLock для синхронизации статических переменных.
источник