Я знаю то использование 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
?
Существует несколько способов синхронизации доступа к статической переменной.
Используйте синхронный статический метод. Это синхронизирует на объекте класса.
Тест общего класса {
Частный статический int count = 0;
Общественная статическая синхронизированная недейственная инкрементCount () {
Count ++;
}
}
Явно синхронизируется на объекте класса.
Тест общего класса {
Частный статический int count = 0;
общедоступная недейственная инкрементCount () {
синхронизирован (test.class) {
Count ++;
}
}
}
Синхронизация на каком-то другом статическом объекте.
Тест общего класса {
Частный статический int count = 0;
Частный статический конечный объект CountLock = новый объект ();
общедоступная недейственная инкрементCount () {
синхронизирован (CountLock) {
Count ++;
}
}
}
Метод 3 - лучшее во многих случаях, потому что объект блокировки не выставлен вне вашего класса.
Да верно.
Если вы создаете два экземпляра вашего класса
Test t1 = new Test();
Test t2 = new Test();
, то T1.foo и T2.foo оба синхронизируются на одном статическом объекте и, следовательно, блокируют друг друга.
Если вы просто делитесь счетчиком, подумайте об использовании AtomicInteger или другого подходящего класса из пакета java.util.concurrent.atomic:
public class Test {
private final static AtomicInteger count = new AtomicInteger(0);
public void foo() {
count.incrementAndGet();
}
}