Ich weiß, dass die Verwendung des synchronize
Schlüsselworts vor einer Methode die Synchronisation für dieses Objekt bewirkt. Das heißt, 2 Threads, auf denen dieselbe Instanz des Objekts ausgeführt wird, werden synchronisiert.
Da sich die Synchronisation jedoch auf Objektebene befindet, werden 2 Threads, auf denen verschiedene Instanzen des Objekts ausgeführt werden, nicht synchronisiert. Wenn wir eine statische Variable in einer Java-Klasse haben, die von der Methode aufgerufen wird, möchten wir, dass sie über Instanzen der Klasse hinweg synchronisiert wird. Die beiden Instanzen werden in zwei verschiedenen Threads ausgeführt.
Können wir die Synchronisation auf folgende Weise erreichen?
public class Test
{
private static int count = 0;
private static final Object lock= new Object();
public synchronized void foo()
{
synchronized(lock)
{
count++;
}
}
}
Stimmt es, dass die statische Variable jetzt über Klasseninstanzen hinweg synchronisiert ist, da wir ein lock
statisches Objekt definiert haben und das Schlüsselwort synchronized
für diese Sperre verwenden ?count
Test
Antworten:
Es gibt verschiedene Möglichkeiten, den Zugriff auf eine statische Variable zu synchronisieren.
Verwenden Sie eine synchronisierte statische Methode. Dies wird auf dem Klassenobjekt synchronisiert.
Explizite Synchronisierung für das Klassenobjekt.
Synchronisieren Sie mit einem anderen statischen Objekt.
Methode 3 ist in vielen Fällen die beste, da das Sperrobjekt nicht außerhalb Ihrer Klasse verfügbar gemacht wird.
quelle
Test.class
Codebit Ihren Tag synchronisieren und möglicherweise Ihren Tag verderben kann. Außerdem wird die Klasseninitialisierung mit einer Sperre für die gehaltene Klasse ausgeführt. Wenn Sie also verrückte Klasseninitialisierer haben, können Sie sich selbst Kopfschmerzen bereiten.volatile
hilft nicht,count++
weil es eine Lese- / Änderungs- / Schreibsequenz ist. Wie in einer anderen Antwort erwähnt,java.util.concurrent.atomic.AtomicInteger
ist hier wahrscheinlich die richtige Wahl.Test.class
.this
wäre die Sperre für synchronisierte nicht statische MethodenWenn Sie lediglich einen Zähler freigeben , sollten Sie eine AtomicInteger oder eine andere geeignete Klasse aus dem Paket java.util.concurrent.atomic verwenden:
quelle
Ja, das ist wahr.
Wenn Sie zwei Instanzen Ihrer Klasse erstellen
Dann synchronisieren sich t1.foo und t2.foo beide auf demselben statischen Objekt und blockieren sich daher gegenseitig.
quelle
Wir können auch ReentrantLock verwenden , um die Synchronisation für statische Variablen zu erreichen.
quelle
Sie können Ihren Code über die Klasse synchronisieren. Das wäre am einfachsten.
Ich hoffe, Sie finden diese Antwort hilfreich.
quelle
Test.class
und das Verhalten beeinflussen kann. Aus diesem Grund wird die Synchronisierunglock
möglicherweise bevorzugt.