Table des matières
Verrouillage
Défauts synchronisés
méthodes
ReentrantLock
Méthode de construction
Méthodes courantes
ReadWriteLock
ReentrantReadWriteLock
构造方法
常用的方法
参考文章
Maison Java javaDidacticiel Verrouiller le partage du résumé d'utilisation

Verrouiller le partage du résumé d'utilisation

Jun 23, 2017 am 10:50 AM
lock

Verrouillage

Dans l'article précédent, nous avons expliqué comment utiliser le mot-clé synchronisé pour obtenir un accès synchrone. Dans cet article, nous continuons à discuter de ce problème. À partir de Java 5, un autre moyen d'obtenir un accès synchrone est fourni dans le package java.util.concurrent.locks, à savoir Lock.

Certains amis peuvent demander, puisque l'accès synchronisé peut être obtenu via la synchronisation, pourquoi devons-nous fournir un verrouillage ? Cette question sera abordée ci-dessous. Cet article commence par les lacunes de synchronisé, puis décrit les classes et interfaces couramment utilisées sous le package java.util.concurrent.locks, et aborde enfin les éléments suivants sur le concept de verrous

Défauts synchronisés

Nous avons dit plus tôt qu'il existe deux situations dans lesquelles un thread synchronisé libère le verrou :

  1. Le bloc de code ou la méthode synchronisée est exécuté

  2. Lorsqu'une exception se produit dans un bloc de code ou une méthode de synchronisation, la jvm libère automatiquement le verrou

Vous pouvez voir sur le verrou de libération synchronisé au-dessus de Out, le verrou ne sera libéré qu'après l'exécution du bloc de code synchronisé ou si une exception se produit. Si le programme dans le bloc de code est bloqué pour des raisons d'E/S, le thread ne sera jamais libéré. le verrou, mais à ce moment-là, d'autres threads exécuteront toujours d'autres programmes, ce qui affecte grandement l'efficacité d'exécution du programme. Nous avons maintenant besoin d'un mécanisme qui puisse empêcher le thread d'attendre indéfiniment et de répondre aux interruptions. lock

De plus, s'il existe un programme qui contient plusieurs threads de lecture et un thread d'écriture, nous pouvons savoir que synchronisé ne peut être exécuté que par un seul thread, mais nous avons besoin de plusieurs threads de lecture. lire en même temps, donc utiliser synchronisé n'est certainement pas possible, mais nous utilisons le verrouillage de la même manière. Cela peut être fait

Verrouillage

En regardant le. API, nous pouvons voir que Lock est une interface, donc les objets ne peuvent pas être créés directement, mais nous pouvons utiliser les classes qu'elle implémente pour créer un objet, ne nous inquiétez pas pour cela, jetons d'abord un coup d'œil aux méthodes implémentées par Lock. class Nous expliquerons l'implémentation spécifique en détail lors de la présentation des classes qu'elle implémente

méthodes

  • lock() Obtenez le verrou, sinon. il attendra éternellement

  • unlock() Libérez le verrou

  • tryLock() Essayez d'acquérir le verrou si le verrou est acquis avec succès, exécutez-le. Si le verrou n'est pas acquis avec succès, alors il n'y aura pas d'attente

  • lockInterruptibly() Si le thread actuel n'est pas interrompu, le verrou est acquis.

ReentrantLock

ReentrantLock est un verrou réentrant C'est une classe qui implémente l'interface Lock est un mécanisme d'allocation de threads, réentrant. Cela signifie qu'il est toujours alloué au thread qui a récemment obtenu le verrou. Il s'agit d'un mécanisme d'allocation injuste, et bien sûr, afin de résoudre ce phénomène, la méthode de construction de ReentrantLock fournit également un paramètre équitable . juste est vrai, cela signifie qu'en utilisant le mécanisme d'allocation équitable, le thread avec le temps d'attente le plus long obtiendra le verrou

Méthode de construction

  • ReentrantLock() Créer un objet et utiliser le mécanisme réentrant par défaut

  • ReentrantLock(boolean fair) Si fair est vrai, alors le mécanisme d'allocation équitable est utilisé

Méthodes courantes

  • lock() Acquérir le verrou S'il n'est pas acquis, il bloquera toujours

.

Ce qui suit utilise un programme pour démontrer l'utilisation de la méthode de verrouillage suivante. Le code est le suivant :

//实现接口的线程类public class MyThread implements Runnable {public ReentrantLock rLock = null;  //注意这里的锁一定要是全局变量,否则每一个线程都创建一把锁,那么将会毫无意义
 public MyThread() {this.rLock = new ReentrantLock(); // 创建默认的可重入锁}// 将unlock方法放在finally中确保执行中代码出现异常仍然能够释放锁,否则将会造成其它的线程阻塞public void display() {this.rLock.lock(); // 获取锁try {for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "正在输出"+ i);
            }
        } finally {this.rLock.unlock(); // 释放锁,注意这步是一定需要的}

    }@Overridepublic void run() {this.display(); // 调用display方法}

}//线程的测试类,主要是创建对象启动线程public class Test {public static void main(String[] args) {final MyThread thread = new MyThread(); // 创建对象// 下面创建两个线程,并且直接启动,new Thread(thread).start();new Thread(thread).start();

    }
}
Copier après la connexion

Exécutez le. ci-dessus pour obtenir le résultat comme indiqué ci-dessous :

Verrouiller le partage du résumé dutilisation

À partir des résultats ci-dessus, nous pouvons voir que les threads génèrent un par un, et le suivant ne peut être exécuté qu'après avoir attendu la fin de la sortie d'un thread. Un thread, ici est uniquement pour le code entre le verrouillage et le déverrouillage, l'autre code n'est pas contrôlé

Remarque : La création ici peut être répétée. L'objet verrouillé doit être une variable globale pour chaque thread et un objet pouvant être partagé. Si vous créez cet objet dans la méthode d'affichage, cela n'a aucun sens car. chaque thread n'utilise pas du tout le même. Lock

  • boolean tryLock() Essayez d'abord d'acquérir le verrou. Si le verrou est acquis, exécutez-le, sinon. cela n'attendra pas éternellement

Utilisez un morceau de code pour essayer la méthode suivante :

<. 🎜>
//实现接口的线程类public class MyThread implements Runnable {public ReentrantLock rLock = null; // 注意这里的锁一定要是全局变量,否则每一个线程都创建一把锁,那么将会毫无意义public MyThread() {this.rLock = new ReentrantLock(); // 创建默认的可重入锁}// 将unlock方法放在finally中确保执行中代码出现异常仍然能够释放锁,否则将会造成其它的线程阻塞public void display() {if (this.rLock.tryLock()) // 如果获取了锁{try {for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName()
                            + "正在输出" + i);
                }
            } finally {this.rLock.unlock(); // 释放锁,注意这步是一定需要的}

        } else {
            System.out.println(Thread.currentThread().getName()
                    + "获取锁失败,我将不会一直等待........");
        }

    }@Overridepublic void run() {this.display(); // 调用display方法}

}//线程的测试类,主要是创建对象启动线程public class Test {public static void main(String[] args) {final MyThread thread = new MyThread(); // 创建对象// 下面创建两个线程,并且直接启动,new Thread(thread).start();new Thread(thread).start();

    }
}
Copier après la connexion

执行后的Verrouiller le partage du résumé dutilisation如下图:

Verrouiller le partage du résumé dutilisation

从上面的Verrouiller le partage du résumé dutilisation我们知道线程0获取了锁开始执行,但是线程1并没有获取锁,但是使用的是tryLock并不是lock,因此不会一直等待下去,所以直接程序向下运行,直接跳过上锁的代码段,因此就输出了上面的那句话后直接结

ReadWriteLock

从API中可以知道,这个也是一个接口,用于实现读写线程,他有两个方法:Lock readLock(),Lock writeLock() 分别用于获得读锁和写锁,指定特定的锁可以实现特定的功能,比如读锁可以在写线程在执行的情况下可以实现多个读线程进行操作,下面我们来介绍它的具体的实现的类ReentrantReadWriteLock

ReentrantReadWriteLock

这个类也是一个可重入分配的类,当然前面已经说过了什么是可重入,现在我们来说说说这个类的详细的用法

构造方法

  • ReentrantReadWriteLock() 使用默认(非公平)的排序属性创建一个新的 ReentrantReadWriteLock。

  • ReentrantReadWriteLock(boolean fair) 使用给定的公平策略创建一个新的ReentrantReadWriteLock。

常用的方法

  • ReentrantReadWriteLock.ReadLock readLock() 用于返回读取操作的锁

前面已经说过读取操作的锁是用来实现多个线程共同执行的,代码如下:

//实现接口的线程类public class MyThread implements Runnable {public ReentrantReadWriteLock rwlock = null;public Lock rLock = null;public MyThread() {this.rwlock = new ReentrantReadWriteLock(); // 创建对象,使用的是非公平的this.rLock = this.rwlock.readLock(); // 获取读取锁对象}// 将unlock方法放在finally中确保执行中代码出现异常仍然能够释放锁,否则将会造成其它的线程阻塞public void display() {this.rLock.lock(); // 获取读取锁try {for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + "正在输出"+ i);
            }
        } finally {this.rLock.unlock(); // 释放锁,注意这步是一定需要的}

    }@Overridepublic void run() {this.display(); // 调用display方法}

}//线程的测试类,主要是创建对象启动线程public class Test {public static void main(String[] args) {final MyThread thread = new MyThread(); // 创建对象// 下面创建两个线程,并且直接启动,for(int i=0;i<5;i++)
        {new Thread(thread).start();
        }
        


    }
}
Copier après la connexion

执行上面的程序Verrouiller le partage du résumé dutilisation如下:

Verrouiller le partage du résumé dutilisation

从上面的Verrouiller le partage du résumé dutilisation可以知道,其实使用读取操作是多个线程同时进行读取的操作,因此一定要小心谨慎的使用,根据自己的需求,一般不能在里面进行修改了,因为出现Verrouiller le partage du résumé dutilisation不准确的Verrouiller le partage du résumé dutilisation,这个就不多说了,相信大家都明白,总之要小心使用

  • ReentrantReadWriteLock.WriteLock writeLock() 返回用于写入操作的锁

写入操作的锁和读取操作的锁不一样了,因为一次只能允许一个线程执行写入操作。

并且如果一个线程已经占用了读锁,另外一个线程申请写锁将会一直等待线程释放读锁。

如果一个线程已经占用了写锁,另外一个线程申请读锁,那么这个线程将会一直等待线程释放写锁才能执行。

总之意思就是写线程和读线程不能同时执行,但是多个读线程可以同时执行

下面将使用一个程序详细的体会以下读写锁的综合使用,代码如下:

//实现接口的线程类public class MyThread {public ReentrantReadWriteLock rwlock = null;public Lock rLock = null;public Lock wLock = null;public ArrayList<Integer> arrayList = null;public MyThread() {this.rwlock = new ReentrantReadWriteLock(); // 创建对象,使用的是非公平的this.rLock = this.rwlock.readLock(); // 获取读取锁对象arrayList = new ArrayList<>(); // 实例化this.wLock = this.rwlock.writeLock(); // 获取写入锁对象}// 将unlock方法放在finally中确保执行中代码出现异常仍然能够释放锁,否则将会造成其它的线程阻塞// //向arraylist中写入数据public void put() {this.wLock.lock(); // 获取写入锁try {for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()
                        + "正在执行写入操作,写入" + i);this.arrayList.add(i);
            }
        } finally {this.wLock.unlock();
        }

    }// 从arraylist中读取数据,这里只是随机读取使用的是get,并没有做什么修改,因为这仅仅是读取操作,如果进行了修改必须实现同步public void get() {this.rLock.lock(); // 获取读取操作的锁Random random = new Random();if (!arrayList.isEmpty()) {try {for (int i = 0; i < 10; i++) {int index = random.nextInt(this.arrayList.size() - 1);int data = this.arrayList.get(index);
                    System.out.println(Thread.currentThread().getName()
                            + "正在读取数据     " + data);
                }
            } finally {this.rLock.unlock();

            }
        } else {
            System.out.println("ArrayList为空");
        }

    }

}//线程的测试类,主要是创建对象启动线程public class Test {public static void main(String[] args) {final MyThread thread = new MyThread(); // 创建对象ArrayList<Thread> arrayList = new ArrayList<>();/*         * 创建8个读线程,2个写线程         */for (int i = 0; i < 2; i++) {
            arrayList.add(new Thread() {@Overridepublic void run() {
                    thread.put();
                }
            });

        }        for(int i=0;i<8;i++)
        {
            arrayList.add(new Thread(){@Overridepublic void run() {
                    thread.get();
                }
            });
        }        
        
        
        for (Thread t : arrayList) {
            t.start();
        }

    }
}
Copier après la connexion

Verrouiller le partage du résumé dutilisation如下图:

Verrouiller le partage du résumé dutilisation

从上面可以看出写入线程都是一个一个执行的,读取线程是一起执行的

注意: 所有的锁对象对于线程来说必须是全局变量,否则毫无意义。读线程只能进行不影响线程安全性的操作,比如不能进行对数据的修改插入,如果想要进行修改的话必须还要使用锁对必要的代码实现同步操作

参考文章


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!

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

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

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)

Comment utiliser Lock dans le multithreading Java Comment utiliser Lock dans le multithreading Java May 12, 2023 pm 02:46 PM

Après Jdk1.5, sous le package java.util.concurrent.locks, il existe un ensemble d'interfaces et de classes qui implémentent la synchronisation des threads. En matière de synchronisation des threads, tout le monde peut penser au mot-clé synchronisé, qui est un mot-clé intégré. mot-clé en Java. Il gère la synchronisation des threads, mais ce mot-clé présente de nombreux défauts et n'est pas très pratique et intuitif à utiliser, donc Lock apparaît ci-dessous, nous allons comparer et expliquer Lock. Habituellement, lorsque nous utilisons le mot-clé synchronisé, nous rencontrerons les problèmes suivants : (1) Incontrôlabilité, impossible de verrouiller et de déverrouiller les verrous à volonté. (2) L'efficacité est relativement faible. Par exemple, nous lisons actuellement deux fichiers simultanément.

Quelles sont les manières d'utiliser Lock en Java ? Quelles sont les manières d'utiliser Lock en Java ? Apr 23, 2023 pm 08:52 PM

1. Fonction (1) La méthode Lock pour acquérir des verrous prend en charge l'interruption, aucune acquisition après un délai d'attente et n'est pas bloquante (2) Elle améliore la sémantique. L'endroit où verrouiller et déverrouiller doit être écrit (3) Le verrouillage explicite du verrou peut nous apporter. Livré avec une bonne flexibilité, mais en même temps, nous devons libérer manuellement le verrou (4) Objet de condition de condition de support (5) Autoriser plusieurs threads de lecture à accéder aux ressources partagées en même temps 2. Utilisation du verrouillage //Obtenir le verrou voidlock() //Si le thread actuel n'a pas été interrompu, acquérir le verrou voidlockInterruptably()//Renvoyer une nouvelle instance de Condition liée à cette instance de Lock ConditionnewCondition()//Lock uniquement lorsqu'il est appelé

Quelles fonctionnalités la classe Java Lock fournit-elle ? Quelles fonctionnalités la classe Java Lock fournit-elle ? Apr 21, 2023 am 08:16 AM

Remarque 1. Lock est une interface du package java.util.concurent, qui définit une série de méthodes d'opération de verrouillage. 2. L'interface Lock comprend principalement les classes d'implémentation ReentrantLock, ReentrantReadWriteLock, ReentrantReadWriteLock et WriteLock. Différent de Synchronized, Lock fournit des interfaces associées telles que l'acquisition et la libération de verrous, ce qui le rend plus flexible à utiliser et plus complexe à utiliser. InstanceReentrantReadWriteLocklock=newReentrantReadWriteLock();Lockread

Pourquoi Java doit-il fournir Lock au lieu d'utiliser simplement le mot-clé synchronisé ? Pourquoi Java doit-il fournir Lock au lieu d'utiliser simplement le mot-clé synchronisé ? Apr 20, 2023 pm 05:01 PM

Résumé : Le mot clé synchronisé est fourni en Java pour garantir qu'un seul thread peut accéder au bloc de code synchronisé. Puisque le mot-clé synchronisé a été fourni, pourquoi l'interface Lock est-elle également fournie dans le package Java SDK ? Est-ce une réinvention inutile de la roue ? Aujourd’hui, nous discuterons ensemble de cette question. Le mot-clé synchronisé est fourni en Java pour garantir qu'un seul thread peut accéder au bloc de code synchronisé. Puisque le mot-clé synchronisé a été fourni, pourquoi l'interface Lock est-elle également fournie dans le package Java SDK ? Est-ce une réinvention inutile de la roue ? Aujourd’hui, parlons-en ensemble

Quelles sont les méthodes d'acquisition de verrous en Java ? Quelles sont les méthodes d'acquisition de verrous en Java ? May 19, 2023 pm 01:13 PM

1. Les méthodes d'acquisition lock(), tryLock(), tryLock(longtime, TimeUnitunit) et lockInterruptably() sont toutes utilisées pour acquérir des verrous. (1) La méthode lock() est la méthode la plus couramment utilisée pour obtenir des verrous. Si le verrou a été acquis par un autre thread, attendez. (2) La méthode tryLock() a une valeur de retour, ce qui signifie qu'elle est utilisée pour tenter d'acquérir le verrou. Si l'acquisition réussit, elle renvoie vrai. Si l'acquisition échoue (c'est-à-dire que le verrou a été acquis par un autre). thread), il renvoie false, ce qui signifie ceci La méthode retourne immédiatement quoi qu'il arrive. Vous n'attendrez pas là-bas si vous ne parvenez pas à obtenir la serrure. (3) essayezLoc

Problèmes courants dans la pile technologique Java et leurs solutions Problèmes courants dans la pile technologique Java et leurs solutions Sep 06, 2023 am 09:59 AM

Problèmes courants dans la pile technologique Java et leurs solutions Lors du développement d'applications Java, nous rencontrons souvent des problèmes, tels que des problèmes de performances, des fuites de mémoire, la sécurité des threads, etc. Cet article présentera quelques problèmes courants et leurs solutions, et donnera des exemples de code correspondants. 1. Problèmes de performances 1.1 Problèmes de performances causés par la création fréquente d'objets La création fréquente d'objets entraînera des déclenchements fréquents de garbage collection, affectant ainsi les performances du programme. La solution consiste à utiliser le pooling d’objets ou la mise en cache pour réutiliser les objets. Exemple de code : //Réutiliser des objets à l'aide d'un pool d'objets

Authentification de sécurité PHP avec Auth0 Lock Authentification de sécurité PHP avec Auth0 Lock Jul 24, 2023 am 11:16 AM

Vérification de la sécurité PHP via Auth0Lock Avec le développement d'Internet, de plus en plus d'applications nécessitent une authentification des utilisateurs et une vérification de sécurité pour protéger la confidentialité des utilisateurs et la sécurité des données. PHP est un langage backend largement utilisé qui offre de nombreuses façons de mettre en œuvre une validation sécurisée. Auth0 est une plateforme d'authentification et d'autorisation populaire qui offre aux développeurs un moyen flexible et sécurisé de mettre en œuvre l'authentification des utilisateurs. Auth0Lock est celui fourni par Auth0

Quelle est la différence entre Lock et Synchronized en Java Quelle est la différence entre Lock et Synchronized en Java Apr 17, 2023 pm 07:19 PM

1. D'un point de vue fonctionnel, Lock et Synchronized sont tous deux des outils utilisés en Java pour résoudre les problèmes de sécurité des threads. 2. D'un point de vue fonctionnel, Synchronized est le mot-clé de synchronisation en Java, Lock est l'interface fournie dans le package J.U.C. , et cela L'interface a de nombreuses classes d'implémentation, y compris l'implémentation de verrous réentrants tels que ReentrantLock Synchronized peut contrôler la force du verrou de deux manières. L'une consiste à modifier le mot-clé synchronisé au niveau de la méthode. sur le bloc de code. Vous pouvez utiliser le cycle de vie de l'objet de verrouillage synchronisé pour contrôler la portée du verrou. L'objet de verrouillage est un objet statique ou une paire de classes.

See all articles