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面试题与答案】整理推荐

 

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • charles乱码怎么解决_charles乱码怎么解决

    charles乱码怎么解决_charles乱码怎么解决前言当使用Charles抓包时,发现数据都是乱码,这时需要安装证书解决办法1.点击charles窗口,点击左上角Help->SSLProxying→InstallCharles

    2022年7月28日
    1
  • 数学速算法_三年级数学时分秒换算口诀+精选思维奥数题整理汇总[通俗易懂]

    数学速算法_三年级数学时分秒换算口诀+精选思维奥数题整理汇总[通俗易懂]文末有打印方法时间单位换算口诀1世纪=100年1年=12月大月(31天)有:1月,3月,5月,7月,8月,10月,12月小月(30天)的有:4月,6月,9月,11月平年2月28天,闰年2月29天平年全年365天,闰年全年366天1日=24小时1时=60分1分=60秒1时=3600秒时间之间的进率都是601时=60分1分=60秒…

    2022年6月15日
    104
  • python之random库

    random库是用于产生并运用随机数的标准库1.random库函数(1)random.seed(a)设置随机种子数,可以是浮点数或整数,如果不设置的话,则random库默认以系统时间产生当作随

    2021年12月29日
    55
  • stringtokenizer是什么意思_string getbytes

    stringtokenizer是什么意思_string getbytesStringTokenizer是一个用来分隔String的应用类。构造函数publicStringTokenizer(Stringstr)publicStringTokenizer(Stringstr,Stringdelim)publicStringTokenizer(Stringstr,Stringdelim,booleanreturnDelims)第一个参

    2022年8月11日
    4
  • Linux搭建 Minecraft 服务器

    Linux搭建 Minecraft 服务器本篇文章介绍使用常规方式和docker容器方式在linux操作系统上搭建最新版本的minecraft服务器,并使用bungeecord配置为群组服务器模式。

    2022年6月18日
    38
  • viewpager循环滚动_jq实现轮播图循环

    viewpager循环滚动_jq实现轮播图循环Viewpager图片自动轮播无限循环是Android开发中经常用到的功能,功能实现起来也比较简单。虽然如此,但是很多情况下做出来的效果并不太让人满意,甚至有些上线的项目自动轮播上也会出现一些bug。比如切换过程中出现空白页面,有些甚至在滑动过程中造成程序崩溃。本篇文章将实现ViewPager图片自动轮播无限循环,而且页面切换效果非常流畅。还是先看效果图:页面循环切换最容易出现问题的地方…

    2022年10月5日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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