Maison Java javaDidacticiel Explication détaillée de l'utilisation du blocage des threads de la classe LockSupport dans la programmation multithread Java

Explication détaillée de l'utilisation du blocage des threads de la classe LockSupport dans la programmation multithread Java

Jan 05, 2017 pm 03:56 PM

LockSupport est une primitive de blocage de thread de base utilisée pour créer des verrous et d'autres classes de synchronisation.
Les fonctions de park() et unpark() dans LockSupport sont respectivement de bloquer et de débloquer les threads, et park() et unpark() ne rencontreront pas de blocages pouvant être causés par "Thread.suspend et Thread.resume". "question.
Parce que park() et unpark() ont des autorisations ; la course entre le thread appelant park() et un autre thread essayant de unpark() restera active.

Utilisation de base
LockSupport est très similaire à un sémaphore binaire (une seule licence est disponible pour l'utilisation Si la licence n'a pas été occupée, le thread actuel obtient la licence et continue l'exécution si la licence est disponible). a été occupé, le thread actuel est bloqué, en attente d'obtenir l'autorisation.

public static void main(String[] args)
{
   LockSupport.park();
   System.out.println("block.");
}
Copier après la connexion

Exécutez ce code et vous constaterez que le fil de discussion principal est toujours bloqué. Étant donné que la licence est occupée par défaut, la licence ne peut pas être obtenue lors de l'appel de park(), elle entre donc dans l'état de blocage.

Le code suivant : libérez d'abord l'autorisation, puis obtenez l'autorisation, et le thread principal peut se terminer normalement. L'acquisition et la libération des autorisations LockSupport correspondent généralement. Si vous déparkez plusieurs fois, il n'y aura aucun problème avec un seul parcage. Le résultat est que l'autorisation est disponible.

public static void main(String[] args)
{
   Thread thread = Thread.currentThread();
   LockSupport.unpark(thread);//释放许可
   LockSupport.park();// 获取许可
   System.out.println("b");
}
Copier après la connexion

LockSupport n'est pas réentrant Si un thread appelle LockSupport .park() deux fois de suite, le thread restera définitivement bloqué.

public static void main(String[] args) throws Exception
{
 Thread thread = Thread.currentThread();
  
 LockSupport.unpark(thread);
  
 System.out.println("a");
 LockSupport.park();
 System.out.println("b");
 LockSupport.park();
 System.out.println("c");
}
Copier après la connexion

Ce code imprime a et b, mais pas c, car lorsque park est appelé pour la deuxième fois, le thread ne peut pas obtenir l'autorisation et meurt.

Jetons un coup d'œil à la réactivité de LockSupport aux interruptions

public static void t2() throws Exception
{
 Thread t = new Thread(new Runnable()
 {
  private int count = 0;
 
  @Override
  public void run()
  {
   long start = System.currentTimeMillis();
   long end = 0;
 
   while ((end - start) <= 1000)
   {
    count++;
    end = System.currentTimeMillis();
   }
 
   System.out.println("after 1 second.count=" + count);
 
  //等待或许许可
   LockSupport.park();
   System.out.println("thread over." + Thread.currentThread().isInterrupted());
 
  }
 });
 
 t.start();
 
 Thread.sleep(2000);
 
 // 中断线程
 t.interrupt();
 
  
 System.out.println("main over");
}
Copier après la connexion

Le fil de discussion final imprimera le fil de discussion over.true. Cela montre que si le thread est bloqué en appelant park, il peut répondre à la demande d'interruption (l'état de l'interruption est défini sur true), mais il ne lancera pas InterruptedException.

Liste des fonctions LockSupport

// 返回提供给最近一次尚未解除阻塞的 park 方法调用的 blocker 对象,如果该调用不受阻塞,则返回 null。
static Object getBlocker(Thread t)
// 为了线程调度,禁用当前线程,除非许可可用。
static void park()
// 为了线程调度,在许可可用之前禁用当前线程。
static void park(Object blocker)
// 为了线程调度禁用当前线程,最多等待指定的等待时间,除非许可可用。
static void parkNanos(long nanos)
// 为了线程调度,在许可可用前禁用当前线程,并最多等待指定的等待时间。
static void parkNanos(Object blocker, long nanos)
// 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。
static void parkUntil(long deadline)
// 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。
static void parkUntil(Object blocker, long deadline)
// 如果给定线程的许可尚不可用,则使其可用。
static void unpark(Thread thread)
Copier après la connexion


Exemple de LockSupport
Comparez « Exemple 1 » et « Exemple 2 » ci-dessous. peut comprendre plus clairement l’utilisation de LockSupport.
Exemple 1

public class WaitTest1 {
 
  public static void main(String[] args) {
 
    ThreadA ta = new ThreadA("ta");
 
    synchronized(ta) { // 通过synchronized(ta)获取“对象ta的同步锁”
      try {
        System.out.println(Thread.currentThread().getName()+" start ta");
        ta.start();
 
        System.out.println(Thread.currentThread().getName()+" block");
        // 主线程等待
        ta.wait();
 
        System.out.println(Thread.currentThread().getName()+" continue");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
 
  static class ThreadA extends Thread{
 
    public ThreadA(String name) {
      super(name);
    }
 
    public void run() {
      synchronized (this) { // 通过synchronized(this)获取“当前对象的同步锁”
        System.out.println(Thread.currentThread().getName()+" wakup others");
        notify();  // 唤醒“当前对象上的等待线程”
      }
    }
  }
}
Copier après la connexion

Exemple 2

import java.util.concurrent.locks.LockSupport;
 
public class LockSupportTest1 {
 
  private static Thread mainThread;
 
  public static void main(String[] args) {
 
    ThreadA ta = new ThreadA("ta");
    // 获取主线程
    mainThread = Thread.currentThread();
 
    System.out.println(Thread.currentThread().getName()+" start ta");
    ta.start();
 
    System.out.println(Thread.currentThread().getName()+" block");
    // 主线程阻塞
    LockSupport.park(mainThread);
 
    System.out.println(Thread.currentThread().getName()+" continue");
  }
 
  static class ThreadA extends Thread{
 
    public ThreadA(String name) {
      super(name);
    }
 
    public void run() {
      System.out.println(Thread.currentThread().getName()+" wakup others");
      // 唤醒“主线程”
      LockSupport.unpark(mainThread);
    }
  }
}
Copier après la connexion

Exécuter Résultat :

main start ta
main block
ta wakup others
main continue
Copier après la connexion

Explication : La différence entre se garer et attendre. Avant que l'attente bloque le thread, celui-ci doit obtenir le verrou de synchronisation via synchronisé.


Pour des explications plus détaillées sur l'utilisation du blocage de thread de la classe LockSupport dans la programmation multithread Java, veuillez prêter attention au site Web PHP chinois !


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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le logiciel de sécurité de l'entreprise entraîne-t-il l'exécution de l'application? Comment dépanner et le résoudre? Le logiciel de sécurité de l'entreprise entraîne-t-il l'exécution de l'application? Comment dépanner et le résoudre? Apr 19, 2025 pm 04:51 PM

Dépannage et solutions au logiciel de sécurité de l'entreprise qui fait que certaines applications ne fonctionnent pas correctement. De nombreuses entreprises déploieront des logiciels de sécurité afin d'assurer la sécurité des réseaux internes. ...

Comment simplifier les problèmes de cartographie des champs dans l'amarrage du système à l'aide de mapstruct? Comment simplifier les problèmes de cartographie des champs dans l'amarrage du système à l'aide de mapstruct? Apr 19, 2025 pm 06:21 PM

Le traitement de la cartographie des champs dans l'amarrage du système rencontre souvent un problème difficile lors de l'exécution d'amarrage du système: comment cartographier efficacement les champs d'interface du système a ...

Comment obtenir élégamment des noms de variables de classe d'entité pour créer des conditions de requête de base de données? Comment obtenir élégamment des noms de variables de classe d'entité pour créer des conditions de requête de base de données? Apr 19, 2025 pm 11:42 PM

Lorsque vous utilisez MyBatis-Plus ou d'autres cadres ORM pour les opérations de base de données, il est souvent nécessaire de construire des conditions de requête en fonction du nom d'attribut de la classe d'entité. Si vous manuellement à chaque fois ...

Comment Intellij Idea identifie-t-elle le numéro de port d'un projet de démarrage de printemps sans publier un journal? Comment Intellij Idea identifie-t-elle le numéro de port d'un projet de démarrage de printemps sans publier un journal? Apr 19, 2025 pm 11:45 PM

Commencez le printemps à l'aide de la version IntelliJideaultimate ...

Comment convertir les noms en nombres pour implémenter le tri et maintenir la cohérence en groupes? Comment convertir les noms en nombres pour implémenter le tri et maintenir la cohérence en groupes? Apr 19, 2025 pm 11:30 PM

Solutions pour convertir les noms en nombres pour implémenter le tri dans de nombreux scénarios d'applications, les utilisateurs peuvent avoir besoin de trier en groupe, en particulier en un ...

Comment obtenir élégamment les conditions de requête de création de nom de variable de classe d'entité lors de l'utilisation de tkmybatis pour la requête de base de données? Comment obtenir élégamment les conditions de requête de création de nom de variable de classe d'entité lors de l'utilisation de tkmybatis pour la requête de base de données? Apr 19, 2025 pm 09:51 PM

Lorsque vous utilisez TkMyBatis pour les requêtes de base de données, comment obtenir gracieusement les noms de variables de classe d'entité pour créer des conditions de requête est un problème courant. Cet article épinglera ...

Comment convertir en toute sécurité les objets Java en tableaux? Comment convertir en toute sécurité les objets Java en tableaux? Apr 19, 2025 pm 11:33 PM

Conversion des objets et des tableaux Java: Discussion approfondie des risques et des méthodes correctes de la conversion de type de distribution De nombreux débutants Java rencontreront la conversion d'un objet en un tableau ...

Comment utiliser la solution Redis Cache pour réaliser efficacement les exigences de la liste de classement des produits? Comment utiliser la solution Redis Cache pour réaliser efficacement les exigences de la liste de classement des produits? Apr 19, 2025 pm 11:36 PM

Comment la solution de mise en cache Redis réalise-t-elle les exigences de la liste de classement des produits? Pendant le processus de développement, nous devons souvent faire face aux exigences des classements, comme l'affichage d'un ...

See all articles