Maison > Java > JavaBase > Java introduit huit verrous pour vous aider à bien comprendre les verrous d'objet et les verrous de classe

Java introduit huit verrous pour vous aider à bien comprendre les verrous d'objet et les verrous de classe

coldplay.xixi
Libérer: 2021-02-09 18:06:23
avant
3454 Les gens l'ont consulté

Java introduit huit verrous pour vous aider à bien comprendre les verrous d'objet et les verrous de classe

Recommandations d'apprentissage gratuites associées : Tutoriel de base Java

Démonstration de 8 problèmes de verrouillage

1. Accès standard

/*手机类可以发邮件和发短信*/class Phone{
	public synchronized void sendEmail() throws Exception{
		System.out.println("***sendEmail");
	}
	public synchronized void sendSMS() throws Exception{
		System.out.println("***sendSMS");
	}}public class Lock8Demo {
	public static void main(String[] args) throws InterruptedException {
		//创建一个资源类
		Phone phone=new Phone();
		new Thread(()->{
			try {
				phone.sendEmail();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"A").start();
		Thread.sleep(100);
		new Thread(()->{
			try {
				phone.sendSMS();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"B").start();
	}}
Copier après la connexion

Java introduit huit verrous pour vous aider à bien comprendre les verrous dobjet et les verrous de classe
Accès standard, imprimez d'abord un e-mail ou un message texte.
Peu importe qui sera imprimé en premier. Cela dépend de l'exécution du CPU. C'est le thread principal qui les active. Je ne sais pas qui sera programmé en premier.
Afin de garantir l'effet, nous ajoutons thread.sleep(100) entre les codes de A et B. À ce stade, nous pouvons nous assurer que A est imprimé en premier.
Explication :
Tant qu'il existe une classe de ressources, quel que soit le nombre de méthodes de synchronisation dont elle dispose, tant qu'un thread accède d'abord à une méthode de synchronisation dans la classe de ressources, il ne la verrouillera pas méthode est la classe de ressources entière où se trouve la méthode. En d’autres termes, ce qui est verrouillé, c’est l’objet. Ce qu'il verrouille n'est pas la méthode actuelle.
Autrement dit, ces méthodes synchronisées appartiennent toutes à la même classe de ressources et verrouillent toute la classe de ressources.

2. Faites une pause de 4 secondes dans la méthode de courrier électronique. Veuillez d'abord imprimer l'e-mail ou le message texte

/*手机类可以发邮件和发短信*/class Phone{
	public synchronized void sendEmail() throws Exception{
		TimeUnit.SECONDS.sleep(4);		//表示暂停4秒,它是一个枚举类型
		System.out.println("***sendEmail");
	}
	public synchronized void sendSMS() throws Exception{
		System.out.println("***sendSMS");
	}}public class Lock8Demo {
	public static void main(String[] args) throws InterruptedException {
		//创建一个资源类
		Phone phone=new Phone();
		new Thread(()->{
			try {
				phone.sendEmail();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"A").start();
		Thread.sleep(100);
		new Thread(()->{
			try {
				phone.sendSMS();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"B").start();
	}}
Copier après la connexion

Imprimer l'e-mail en premier. Le verrouillage de l'objet du téléphone obtenu par la méthode de synchronisation ne sera pas libéré par la mise en veille. Il sera exécuté immédiatement le moment venu. Alors imprimez d'abord la méthode email
Explication :
C'est similaire à la question 1.
Tant qu'il existe une classe de ressources, quel que soit le nombre de méthodes de synchronisation dont elle dispose, tant qu'un thread accède en premier à n'importe quelle méthode de synchronisation dans la classe de ressources, il ne verrouillera pas cette méthode, mais la méthode. La classe de ressources entière. En d’autres termes, ce qui est verrouillé, c’est l’objet. Ce qu'il verrouille n'est pas la méthode actuelle.
Par exemple : Le moniteur et moi devons utiliser le même téléphone portable pour passer un appel. Je dois attendre que le moniteur termine l'appel avant de pouvoir continuer l'appel. Le moniteur a été débranché pendant un moment alors qu'il l'utilisait, je ne pouvais donc qu'attendre que le moniteur ait fini.

3. Ajout de la méthode ordinaire sayHello, veuillez d'abord imprimer l'e-mail ou bonjour

Imprimez bonjour d'abord

/*手机类可以发邮件和发短信*/class Phone{
	public synchronized void sendEmail() throws Exception{
		TimeUnit.SECONDS.sleep(4);		//表示暂停4秒,它是一个枚举类型
		System.out.println("***sendEmail");
	}
	public synchronized void sendSMS() throws Exception{
		System.out.println("***sendSMS");
	}
	public void sayHello(){
		System.out.println("***sayHello");
	}}public class Lock8Demo {
	public static void main(String[] args) throws InterruptedException {
		//创建一个资源类
		Phone phone=new Phone();
		new Thread(()->{
			try {
				phone.sendEmail();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"A").start();
		Thread.sleep(100);
		new Thread(()->{
			try {
				//phone.sendSMS();
				phone.sayHello();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"B").start();
	}}
Copier après la connexion

Java introduit huit verrous pour vous aider à bien comprendre les verrous dobjet et les verrous de classe
Explication : Après avoir ajouté une méthode courante, il a été constaté qu'elle n'avait rien à voir avec le verrouillage de synchronisation. Il n’est donc pas nécessaire d’attendre que le verrou de synchronisation soit libéré.
Voici un exemple. Le moniteur a utilisé son téléphone portable pour passer un appel. Et je veux emprunter un câble de chargement pour téléphone portable au chef d'équipe. Les deux ne s'excluent pas mutuellement, je peux donc emprunter le câble de chargement avant que le chef d'équipe ait fini d'appeler.

4. Deux téléphones portables, veuillez d'abord imprimer l'e-mail ou le SMS

/*手机类可以发邮件和发短信*/class Phone{
	public synchronized void sendEmail() throws Exception{
		TimeUnit.SECONDS.sleep(4);		//表示暂停4秒,它是一个枚举类型
		System.out.println("***sendEmail");
	}
	public synchronized void sendSMS() throws Exception{
		System.out.println("***sendSMS");
	}
	public void sayHello(){
		System.out.println("***sayHello");
	}}public class Lock8Demo {
	public static void main(String[] args) throws InterruptedException {
		//创建一个资源类
		Phone phone=new Phone();
		Phone phone2=new Phone();
		new Thread(()->{
			try {
				phone.sendEmail();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"A").start();
		Thread.sleep(100);
		new Thread(()->{
			try {
				//phone.sendSMS();
				//phone.sayHello();
				phone2.sendSMS();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"B").start();
	}}
Copier après la connexion

Java introduit huit verrous pour vous aider à bien comprendre les verrous dobjet et les verrous de classe

Explication : Voici un exemple, utilisé par le moniteur Son courrier de loi sur la téléphonie mobile. J'ai appelé avec mon propre téléphone portable. Peu importe qui vient en premier et qui vient en dernier.

5. Deux méthodes de synchronisation statique, le même téléphone mobile, veuillez d'abord imprimer l'e-mail ou le SMS

/*手机类可以发邮件和发短信*/class Phone{
	public static synchronized void sendEmail() throws Exception{
		TimeUnit.SECONDS.sleep(4);		//表示暂停4秒,它是一个枚举类型
		System.out.println("***sendEmail");
	}
	public static synchronized void sendSMS() throws Exception{
		System.out.println("***sendSMS");
	}
	public void sayHello(){
		System.out.println("***sayHello");
	}}public class Lock8Demo {
	public static void main(String[] args) throws InterruptedException {
		//创建一个资源类
		Phone phone=new Phone();
		Phone phone2=new Phone();
		new Thread(()->{
			try {
				phone.sendEmail();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"A").start();
		Thread.sleep(100);
		new Thread(()->{
			try {
				phone.sendSMS();
				//phone.sayHello();
				//phone2.sendSMS();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"B").start();
	}}
Copier après la connexion

Java introduit huit verrous pour vous aider à bien comprendre les verrous dobjet et les verrous de classe
Explication : Cela peut être combiné avec la question 6 Analyse

6. Deux méthodes de synchronisation statique, deux téléphones portables, dois-je d'abord imprimer l'e-mail ou le SMS

/*手机类可以发邮件和发短信*/class Phone{
	public static synchronized void sendEmail() throws Exception{
		TimeUnit.SECONDS.sleep(4);		//表示暂停4秒,它是一个枚举类型
		System.out.println("***sendEmail");
	}
	public static synchronized void sendSMS() throws Exception{
		System.out.println("***sendSMS");
	}
	public void sayHello(){
		System.out.println("***sayHello");
	}}public class Lock8Demo {
	public static void main(String[] args) throws InterruptedException {
		//创建一个资源类
		Phone phone=new Phone();
		Phone phone2=new Phone();
		new Thread(()->{
			try {
				phone.sendEmail();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"A").start();
		Thread.sleep(100);
		new Thread(()->{
			try {
				//phone.sendSMS();
				//phone.sayHello();
				phone2.sendSMS();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"B").start();
	}}
Copier après la connexion

Java introduit huit verrous pour vous aider à bien comprendre les verrous dobjet et les verrous de classe Analyse :
static Appartient à une classe. En d’autres termes, il n’appartient pas à un individu indépendant de l’objet courant. C'est une classe mondiale. Cela nécessite de considérer la différence entre les verrous d'objet et les verrous globaux. Les verrous globaux sont des verrous de classe. À l'heure actuelle, qu'il s'agisse d'un ou de plusieurs téléphones, ils proviennent tous de la même classe de téléphone. Quel que soit l'objet que vous verrouillez maintenant, je dois attendre qu'il libère le verrou avant de pouvoir l'utiliser.

Méthode de synchronisation statique 7.1, 1 méthode de synchronisation normale, le même téléphone portable, veuillez d'abord imprimer l'e-mail ou le message texte

/*手机类可以发邮件和发短信*/class Phone{
	public static synchronized void sendEmail() throws Exception{
		TimeUnit.SECONDS.sleep(4);		//表示暂停4秒,它是一个枚举类型
		System.out.println("***sendEmail");
	}
	public synchronized void sendSMS() throws Exception{
		System.out.println("***sendSMS");
	}
	public void sayHello(){
		System.out.println("***sayHello");
	}}public class Lock8Demo {
	public static void main(String[] args) throws InterruptedException {
		//创建一个资源类
		Phone phone=new Phone();
		Phone phone2=new Phone();
		new Thread(()->{
			try {
				phone.sendEmail();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"A").start();
		Thread.sleep(100);
		new Thread(()->{
			try {
				phone.sendSMS();
				//phone.sayHello();
				//phone2.sendSMS();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"B").start();
	}}
Copier après la connexion

Java introduit huit verrous pour vous aider à bien comprendre les verrous dobjet et les verrous de classe Un statique , Un ordinaire. Le même téléphone est verrouillé. La méthode statique verrouille la classe. Cela équivaut à verrouiller une porte d'école, et l'autre est une méthode de synchronisation ordinaire, qui verrouille l'objet actuel. Par exemple, les enseignants ordinaires. Les objets de la serrure sont différents. Il n'y a pas de conflit

8.1 méthode de synchronisation statique, 1 méthode de synchronisation normale, deux téléphones portables, veuillez d'abord imprimer l'e-mail ou le SMS

/*手机类可以发邮件和发短信*/class Phone{
	public static synchronized void sendEmail() throws Exception{
		TimeUnit.SECONDS.sleep(4);		//表示暂停4秒,它是一个枚举类型
		System.out.println("***sendEmail");
	}
	public synchronized void sendSMS() throws Exception{
		System.out.println("***sendSMS");
	}
	public void sayHello(){
		System.out.println("***sayHello");
	}}public class Lock8Demo {
	public static void main(String[] args) throws InterruptedException {
		//创建一个资源类
		Phone phone=new Phone();
		Phone phone2=new Phone();
		new Thread(()->{
			try {
				phone.sendEmail();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"A").start();
		Thread.sleep(100);
		new Thread(()->{
			try {
				//phone.sendSMS();
				//phone.sayHello();
				phone2.sendSMS();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		},"B").start();
	}}
Copier après la connexion

Java introduit huit verrous pour vous aider à bien comprendre les verrous dobjet et les verrous de classe

Explication : C'est la même chose que ci-dessus.

Explication de la théorie des 8 serrures

1. S'il y a plusieurs méthodes synchronisées dans un objet, tant qu'un thread appelle l'une des méthodes synchronisées à un certain moment, les autres threads ne peuvent qu'attendre. accéder à ces méthodes synchronisées.
L'objet actuel est verrouillé. Après avoir été verrouillé, les autres threads ne peuvent pas entrer dans d'autres méthodes synchronisées de l'objet actuel

Après avoir ajouté une méthode normale, j'ai trouvé que cela n'avait rien à voir avec le verrouillage de synchronisation. .
Après avoir échangé les deux objets, ils n'ont plus le même verrou, et la situation change immédiatement.
Après le passage aux méthodes de synchronisation statique, la situation a immédiatement changé
Toutes les méthodes de synchronisation non statiques utilisent le même verrou ------ l'objet instance lui-même

2. synchronisé pour réaliser la synchronisation Le base de : Chaque objet en Java peut être utilisé comme verrou.
Se manifeste spécifiquement sous les trois formes suivantes :

  1. Pour les méthodes de synchronisation ordinaires, le verrou est l'objet d'instance actuel
  2. Pour les blocs de méthode de synchronisation, le verrou est l'objet configuré entre parenthèses synchronisées.
    Par exemple, écrivez
    synchronisé(this){
    }
  3. dans la méthode pour les méthodes de synchronisation statique, le verrou est l'objet Class de la classe actuelle.

Lorsqu'un processus tente d'accéder à un bloc de code synchronisé, il doit d'abord obtenir le verrou. La sortie ou le lancement d'une exception doit libérer le verrou.
C'est-à-dire qu'après que la méthode de synchronisation non statique d'un objet instance a acquis le verrou, les autres méthodes de synchronisation non statiques de l'objet instance doivent attendre que la méthode qui a acquis le verrou libère le verrou avant de pouvoir acquérir la serrure. Cependant, étant donné que les méthodes de synchronisation non statiques d'autres objets d'instance utilisent des verrous différents des méthodes de synchronisation non statiques de l'objet d'instance, elles peuvent acquérir leurs propres verrous sans attendre la méthode de synchronisation non statique de l'objet d'instance qui a acquis le verrou pour déverrouiller le verrou.

Toutes les méthodes de synchronisation statique utilisent également le même verrou ----- l'objet de classe lui-même.
Les deux verrous sont deux objets différents, il n'y aura donc pas de conditions de concurrence entre les méthodes de synchronisation statique et les méthodes de synchronisation non statiques. (Question 78). Autrement dit, une classe de verrouillage et un verrou ceci, les deux n'entrent pas en conflit.
Mais une fois qu'une méthode de synchronisation statique acquiert le verrou, les autres méthodes de synchronisation statique doivent attendre que la méthode libère le verrou avant de pouvoir acquérir le verrou. Qu'il s'agisse de méthodes statiques d'un même objet d'instance ou d'une méthode de synchronisation statique d'objets d'instance différents, à condition qu'il s'agisse d'objets d'instance de la même classe . (Question 56)

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:csdn.net
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