notify() 和 notifyAll() 有什么区别?「建议收藏」

notify() 和 notifyAll() 有什么区别?「建议收藏」notify()和notifyAll()有什么区别?先解释两个概念。等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池,等待池中的线程不会去竞争该对象的锁。 锁池:只有获取了对象的锁,线程才能执行对象的synchronized代码,对象的锁每次只有一个线程可以获得,其他线程只能在锁池中等待区别:notify()…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

notify() 和 notifyAll() 有什么区别?

先解释两个概念。

  • 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池,等待池中的线程不会去竞争该对象的锁。
  • 锁池:只有获取了对象的锁,线程才能执行对象的 synchronized 代码,对象的锁每次只有一个线程可以获得,其他线程只能在锁池中等待

区别:

notify() 方法随机唤醒对象的等待池中的一个线程,进入锁池;notifyAll() 唤醒对象的等待池中的所有线程,进入锁池。

测试代码

public class TestNotifyNotifyAll {

	private static Object obj = new Object();
	
	public static void main(String[] args) {
		
		//测试 RunnableImplA wait()        
		Thread t1 = new Thread(new RunnableImplA(obj));
		Thread t2 = new Thread(new RunnableImplA(obj));
		t1.start();
		t2.start();
		
		//RunnableImplB notify()
		Thread t3 = new Thread(new RunnableImplB(obj));
		t3.start();
		
		
//		//RunnableImplC notifyAll()
//		Thread t4 = new Thread(new RunnableImplC(obj));
//		t4.start();
	}
	
}


class RunnableImplA implements Runnable {

	private Object obj;
	
	public RunnableImplA(Object obj) {
		this.obj = obj;
	}
	
	public void run() {
		System.out.println("run on RunnableImplA");
		synchronized (obj) {
			System.out.println("obj to wait on RunnableImplA");
			try {
				obj.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("obj continue to run on RunnableImplA");
		}
	}
}

class RunnableImplB implements Runnable {

	private Object obj;
	
	public RunnableImplB(Object obj) {
		this.obj = obj;
	}
	
	public void run() {
		System.out.println("run on RunnableImplB");
		System.out.println("睡眠3秒...");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		synchronized (obj) {
			System.out.println("notify obj on RunnableImplB");
			obj.notify();
		}
	}
}

class RunnableImplC implements Runnable {

	private Object obj;
	
	public RunnableImplC(Object obj) {
		this.obj = obj;
	}
	
	public void run() {
		System.out.println("run on RunnableImplC");
		System.out.println("睡眠3秒...");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		synchronized (obj) {
			System.out.println("notifyAll obj on RunnableImplC");
			obj.notifyAll();
		}
	}
}

结果:仅调用一次 obj.notify(),线程 t1 或 t2 中的一个始终在等待被唤醒,程序不终止

run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplB
睡眠3秒...
notify obj on RunnableImplB
obj continue to run on RunnableImplA

 把 t3 注掉,启动 t4 线程。调用 obj.notifyAll() 方法

public class TestNotifyNotifyAll {

	private static Object obj = new Object();
	
	public static void main(String[] args) {
		
		//测试 RunnableImplA wait()        
		Thread t1 = new Thread(new RunnableImplA(obj));
		Thread t2 = new Thread(new RunnableImplA(obj));
		t1.start();
		t2.start();
		
//		//RunnableImplB notify()
//		Thread t3 = new Thread(new RunnableImplB(obj));
//		t3.start();
		
		
		//RunnableImplC notifyAll()
		Thread t4 = new Thread(new RunnableImplC(obj));
		t4.start();
	}
	
}

 

 结果:t1、t2线程均可以执行完毕

run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplC
睡眠3秒...
notifyAll obj on RunnableImplC
obj continue to run on RunnableImplA
obj continue to run on RunnableImplA

 


【Java面试题与答案】整理推荐

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/195903.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • allow_url_fopen设置

    allow_url_fopen设置使用file,fopen或file_get_contents函数打开远程url时,需要PHP配置中(php.ini)将allow_url_fopen的值设置为On。按照默认设置,这个值本身就是On的。如果allow_url_fopen已经为on,但file,fopen,file_get_contents依然报错,就是服务器的DNS问题,造成了路由结果中有部份路由执行超时,最终PHP执行…

  • esid是什么意思_es unassigned

    esid是什么意思_es unassignedESN(ElectronicSerialNumbers):电子序列号。在CDMA系统中,是鉴别一个物理硬件设备唯一的标识。也就是说每个手机都用这个唯一的ID来鉴别自己,就跟人的身份证一样。一个ESN有32bits,也就是32/8=4bytes。ESN用8位的16进制来表示,如0x801EA066。随着CDMA移动设别的增多,ESN已经不够用了,所以推出了位数更多的MEID。M…

  • python基础(1)python语法规范

    python基础(1)python语法规范python语法规范python的语法规范非常重要,简洁明了是python的特性,以下是python语法的一些说明python3的编码格式是unicode(utf-8)标识符的规则:由字母、数字

  • 深度学习环境搭建之cuda、cudnn以及pytorch和torchvision的whl文件安装方法

    深度学习环境搭建之cuda、cudnn以及pytorch和torchvision的whl文件安装方法一、前言假设已经装好了pycharm、anaconda,接下来需要安装新版的显卡驱动,安装cuda、cudnn、pytorch和pytorchvision,这几个环境的版本互相关联,为了能使用更新的项目,尽量安装最新版本的环境。二、安装新版显卡驱动1、安装前的检查在安装新版显卡驱动之前,先在cmd中输入:nvidia-smi注意:-符号与nvidia和smi不能有空格。右上角的CUDAVersion11.1表示最高能安装CUDA11.1的版本,如果CUDA11.1

  • 启动马达接线实物图_电机的星三角降压启动实物接线图怎么画?

    启动马达接线实物图_电机的星三角降压启动实物接线图怎么画?展开全部电机的星三角降压启动实物接线图如下:基本原理就32313133353236313431303231363533e4b893e5b19e31333365666265是:启动时先用Y型接法电路,使得电机加载电压为220V,这样减少系统负荷防止过载;电机启动后,改成三角型接法电路,使得电压为380V,进行正常运转。这样的起动电流只有全压起动时的1/3,有效保护电机以及电路系统,防止电流过载…

  • 利用泛型抽取Dao层,加事务注解问题(java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType)

    利用泛型抽取Dao层,加事务注解问题(java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType)

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号