3

J'ai une classe avec des variables statiques, et plusieurs threads auront des instances de cette classe.Est-ce qu'un ReentrantLock est assez sûr pour protéger l'accès multithread à une variable statique

La variable statique qui me concerne est un Thread, qui va faire apparaître un message d'une file d'attente et l'envoyer dans un e-mail, jusqu'à ce que la file d'attente soit vide. Chaque fois qu'un message est ajouté à la file d'attente, je vérifie si le thread est vivant. Sinon, je le redémarre.

if (mailThread == null) 
{ 
    mailThread = new Thread(mailSender); 
    mailThread.start(); 
} 
else if (!mailThread.isAlive()) 
{ 
    mailThread = new Thread(mailSender); 
    mailThread.start(); 
} 

Dans another question, on a dit que les variables statiques doivent être utilisées dans un bloc synchronisé.

Ma question est, serait-il sûr d'utiliser simplement un ReentrantLock pour ces contrôles? Ou dois-je utiliser synchronized? Ou les deux?

+0

_... Je vérifie pour voir si le fil est vivant. Si ce n'est pas le cas, je le redémarre._ +1 pour penser à la disponibilité, mais si vous voulez qu'un thread soit toujours disponible, une meilleure stratégie consiste à écrire un fil qui ne meurt jamais. (Je suppose que ce 'mailThread' n'exécute aucun code étranger.Si vous avez besoin d'exécuter du code étranger, il est probablement préférable de le mettre en sandbox dans son propre processus séparé.) –

Répondre

1

Vous pouvez utiliser ReentrantLock ou un bloc synchronisé. Les deux sont également sûrs. Bien qu'il existe une différence de performance dans certaines situations. Consultez ces repères: Benchmark 1Benchmark 2.

0

Selon le docs:

A rentrante exclusion mutuelle de verrouillage avec le même comportement de base et sémantique que le verrouillage du moniteur implicite accessible à l'aide des méthodes et synchronisées déclarations, mais avec des fonctionnalités étendues. A ReentrantLock appartient au thread qui s'est verrouillé avec succès la dernière fois, mais ne l'a pas encore déverrouillé. Un verrou d'invocation de threads renverra avec succès le verrou lorsque le verrou n'appartient pas à un autre thread. La méthode retournera immédiatement si le thread actuel possède déjà le verrou . Cela peut être vérifié en utilisant les méthodes isHeldByCurrentThread() et getHoldCount().

Donc un ReentrantLock doit être suffisamment sûr.