2010-01-25 4 views
4

Je connais en C# quand vous avez un objet que vous voulez utiliser comme un verrou pour le multi-thread, vous devez le déclarer comme statique à l'intérieur d'une classe, que l'instance de classe va exécuter dans un thread séparé.Les objets verrouillés dans Java doivent-ils être statiques?

Cela vaut-il également pour Java? Quelques exemples en ligne semblent déclarer l'objet de verrou comme final seulement ...

Éditer: J'ai une ressource que je veux limiter à seulement un accès de fil à la fois. Une classe qui étend Thread sera utilisée pour créer plusieurs instances et démarrée en même temps. Que devrais-je utiliser?

Merci.

+0

En fait, si vous voulez verrouiller toute la classe, vous pouvez simplement faire: synchronisé (MyClass.class) {...} Vous n'avez pas besoin d'un objet de verrouillage statique. Sauf si vous avez plusieurs ressources. Vous pouvez également utiliser java.util.concurrent.locks. * Qui ont beaucoup de types de verrous utiles avec plus de flexibilité. –

Répondre

6

Dépend du contexte dans lequel ils doivent être utilisés. Si vous voulez un verrou par instance, laissez static. Si vous voulez un verrou par classe, utilisez static. En effet en effet le garder final.

+0

Merci, vous en devez un autre :-P –

+2

Si vous voulez un verrou par classe, alors vous faites probablement quelque chose de mal (cela peut être utile pour les caches, mais en général les statistiques mutables sont mauvaises). –

+0

J'ai une ressource que je veux limiter à un seul accès au thread à la fois. Une classe qui étend Thread sera utilisée pour créer plusieurs instances et démarrée en même temps. Que devrais-je utiliser? –

2

Pas

En Java, il est possible d'utiliser des éléments non statiques comme des serrures.

private Object lock = new Object(); 

public void test(){ 
    synchronized (lock) { 
     // your code 
    } 
} 
+0

Oui, cela compile :) – BalusC

+1

Comme IntelliJ aime me le dire "La synchronisation sur un champ non final est peu susceptible d'avoir une sémantique utile." – Kylar

3

Réponse simple, non. Longue réponse, cela dépend de ce que vous voulez.

private static final Object STATIC_LOCK = new Object(); 

private final Object lock = new Object(); 

public void doSomething() { 
    synchronized (STATIC_LOCK) { 
     // At most, one thread can enter this portion 
    } 

    synchronized (lock) { 
     // Many threads can be here at once, but only one per object of the class 
    } 
} 

Cela étant dit, je vous recommande de regarder les serrures fournies dans java.util.concurrent.locks. En utilisant java.util.concurrent.locks.Lock vous pouvez effectuer les opérations suivantes:

Lock l = ...; 
l.lock(); 
try { 
    // access the resource protected by this lock 
} finally { 
    l.unlock(); 
} 
+0

Cela clarifie encore plus. Merci. –

Questions connexes