必威体育Betway必威体育官网
当前位置:首页 > IT技术

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

时间:2019-10-16 00:40:00来源:IT技术作者:seo实验室小编阅读:50次「手机版」
 

notifyall

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

专栏:

文章与源码汇总于  Gitee

微信公众技术实践推文  constXiong

每天持续更新中.......

相关阅读

notifyDataSetChanged() 动态更新ListView

有时候我们需要修改已经生成的列表,添加或者修改数据,notifyDataSetChanged()可以在修改适配器绑定的数组后,不用重新刷新Activity,通

Java中notify和notifyAll的区别 - 何时以及如何使用

Java  notify   vs notifyAll   notify和notifyAll方法之间有什么区别是棘手的Java问题之一! Condition 是个什么玩

NotifyIcon控件的使用

一、NotifyIcon控件右键菜单的设置二、NotifyIcon控件闪烁效果实现Windows通知栏可以显示应用程序的图标以当应用程序窗口隐藏时,

notifyDataSetInvalidated()和notifyDataSetChanged()

简单的说就是notifyDataSetChanged()会记住你划到的位置,重新加载数据的时候不会改变位置,只是改变了数据; 而用notifyDataSetInv

notifyDataSetChanged()刷新数据不更新原因

使用Listview的时候: 当要动态显示更改后的数据(例如数据库改动), 很多人应该都用过notifyDataSetChanged();这个方法来刷新Listv

分享到:

栏目导航

推荐阅读

热门阅读