Maison > Java > javaDidacticiel > Introduction à l'utilisation de la classe ReentrantLock dans

Introduction à l'utilisation de la classe ReentrantLock dans

不言
Libérer: 2019-03-30 10:40:28
avant
2568 Les gens l'ont consulté

Cet article vous présente une introduction à l'utilisation de la classe ReentrantLock en Java. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

En Java multi-threading, vous pouvez utiliser le mot-clé synchronisé pour obtenir la synchronisation et l'exclusion mutuelle entre plusieurs threads, mais la nouvelle classe ReentrantLock ajoutée dans JDK 1.5 peut également obtenir le même effet et possède également des fonctions étendues. Plus puissant, comme les verrous reniflants, les notifications de branches multidirectionnelles, les fonctions de verrouillage équitable et de verrouillage injuste (par défaut), et plus flexible à utiliser que synchronisé.

Utilisez ReentrantLock pour réaliser la synchronisation

public class MyService {
    private Lock lock = new ReentrantLock();
    public void testMethod() {
        lock.lock();
        for (int i = 0; i < 10; i++){
            System.out.println("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1)));
        }
        lock.unlock();
    }
}
Copier après la connexion
public class MyThread extends Thread {
    private MyService myService;
    public MyThread(MyService myService) {
        this.myService = myService;
    }
    @Override
    public void run() {
        myService.testMethod();
    }
}
Copier après la connexion
public static void main(String[] args) throws IOException, InterruptedException {
MyService myService = new MyService();
MyThread myThreadA = new MyThread(myService);
        MyThread myThreadB = new MyThread(myService);
        MyThread myThreadC = new MyThread(myService);
        MyThread myThreadD = new MyThread(myService);
        MyThread myThreadE = new MyThread(myService);

        myThreadA.start();
        myThreadB.start();
        myThreadC.start();
        myThreadD.start();
        myThreadE.start();

    }
Copier après la connexion

Appelez la méthode lock() de l'objet ReentrantLock pour acquérir le verrou, et appelez la méthode unLock() pour libérer le verrou.

Depuis l'exécution résultats, actuellement Une fois l'impression du thread terminée, le verrou est libéré et les autres threads peuvent continuer à imprimer. Les données imprimées par le thread sont imprimées en groupes, car le thread actuel détient déjà le verrou, mais l'ordre d'impression entre les threads est aléatoire. .

Utiliser Condition pour implémenter l'attente/notification

Le mot-clé synchronisé est combiné avec les méthodes wait() et notify()/notifyall() pour implémenter le mode d'attente/notification, mais lorsqu'il est utilisé, le mode d'attente/notification est utilisé. JVM appellera aléatoirement la méthode notify() Sélectionnez un thread dans l'état WAITNG à exécuter.

L'utilisation de Condition peut être plus flexible, vous pouvez implémenter une "notification sélective", et vous pouvez spécifier quels threads réveiller et quels threads continuer à attendre.

public class MyService {

    private Lock lock = new ReentrantLock();
    public Condition conditionA = lock.newCondition();
    public Condition conditionB = lock.newCondition();

    public void awaitA() throws InterruptedException {
        lock.lock();

        System.out.println("begin awaitA 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        conditionA.await();

        System.out.println("end awaitA 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        lock.unlock();
    }

    public void awaitB() throws InterruptedException {
        lock.lock();

        System.out.println("begin awaitB 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        conditionB.await();

        System.out.println("end awaitB 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        lock.unlock();
    }

    public void  signalAll_A() throws InterruptedException {
        lock.lock();
        System.out.println("begin signalAll_A 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        conditionA.signalAll();

        lock.unlock();
    }

    public void  signalAll_B() throws InterruptedException {
        lock.lock();
        System.out.println("begin signalAll_B 时间" + System.currentTimeMillis() + "ThreadName=" + Thread.currentThread().getName());

        conditionB.signalAll();

        lock.unlock();
    }
}
Copier après la connexion
public class ThreadA extends Thread {

    private MyService myService;
    public ThreadA(MyService myService) {
        this.myService = myService;
    }

    @Override
    public void run() {
        try {
            myService.awaitA();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
Copier après la connexion
public class ThreadB extends Thread {

    private MyService myService;

    public ThreadB(MyService myService) {
        this.myService = myService;
    }

    @Override
    public void run() {
        try {
            myService.awaitB();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
Copier après la connexion
    public static void main(String[] args) throws IOException, InterruptedException {

        MyService myService = new MyService();

        ThreadA threadA = new ThreadA(myService);
        threadA.setName("a");
        threadA.start();

        ThreadB threadB = new ThreadB(myService);
        threadB.setName("b");
        threadB.start();

        Thread.sleep(3000);
        myService.signalAll_A();

    }
Copier après la connexion
  • La méthode wait() de la classe Object est équivalente à la méthode wait() de la classe Condition.
  • La méthode wait(long timeout) dans la classe Object Équivalent à la méthode wait(long time, TimeUnit unit) dans la classe Condition La méthode notify() dans la classe
  • Object est équivalente. à la méthode signal() dans la classe Condition.
  • Dans la classe Object La méthode notifyAll() est équivalente à la méthode signalAll() dans la classe Condition

De la. Résultats de l'exécution, les threads a et b sont suspendus. Lorsque la méthode myService.signalAll_A() est exécutée, le thread a continue l'exécution, tandis que le thread b est toujours en état d'attente.

Méthodes communes

Classe ReentrantLock

int getHoldCount() interroge le nombre de fois que la méthode lock() est appelée.

final int getQueueLength() estime le nombre de threads en attente du verrou Par exemple. , il y a 5 threads, et 1 thread exécute d'abord la méthode wait(), puis la valeur de retour après avoir appelé cette méthode est 4, indiquant que 4 threads attendent le verrou en même temps.

. int getWaitQueueLength(Condition condition) Renvoie une estimation du nombre de threads en attente d'une condition donnée associée à ce verrou. Par exemple, il y a 5 threads, et chaque thread exécute la méthode wait() du même objet de condition, la valeur renvoyée lors de l'appel. cette méthode est 5.

final boolean hasQueuedThreads() détermine s'il y a des threads en attente de ce verrou.

final boolean hasQueuedThread(Thread thread) détermine si le thread spécifié attend pour acquérir ce verrou.

boolean hasWaiters(Condition condition) Déterminez si le thread a appelé la méthode wait().

void lockInterruptably() lance InterruptedException pour acquérir le verrou, à moins que le thread actuel ne soit interrompu.

Classe de condition

La différence entre void waitUninterruptably() et wait() est que l'exception InterrputedException ne sera pas levée lorsque la méthode interrompu() est appelée.

Cet article est tout ici, c'est fini. Pour plus d'autres contenus passionnants, vous pouvez faire attention à la colonne Java Video Tutorial du site Web PHP chinois !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal