栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA多线程-wait/notify使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA多线程-wait/notify使用

wait/notify使用
  • wait会释放锁,而notify不会释放锁。
  • wait()和notify()是object类的方法,这两个方法必须在synchronized代码块或synchronized修饰的方法中使用,调用这两个方法的代码块必须要获得synchronized。
    实现一个容器,提供两个方法,add,size写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;


public class T03_NotifyHoldingLock { //wait notify

	//添加volatile,使t2能够得到通知
	volatile List lists = new ArrayList();

	public void add(Object o) {
		lists.add(o);
	}

	public int size() {
		return lists.size();
	}
	
	public static void main(String[] args) {
		T03_NotifyHoldingLock c = new T03_NotifyHoldingLock();
		
		final Object lock = new Object();
		
		new Thread(() -> {
			synchronized(lock) {
				System.out.println("t2启动");
				if(c.size() != 5) {
					try {
						lock.wait();//t2释放锁进入等待队列等待别的线程调用notify唤醒进入等待队列再被cpu分配执行机会才会继续向下执行
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println("t2 结束");
				lock.notify();
			}
			
		}, "t2").start();
		
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}

		new Thread(() -> {
			System.out.println("t1启动");
			synchronized(lock) {
				for(int i=0; i<10; i++) {
					c.add(new Object());
					System.out.println("add " + i);
					
					if(c.size() == 5) {
						lock.notify();//不释放锁  只唤醒调用wait();方法的线程t2让他进入等待队列还是要等到t1执行完毕释放锁,
						// T2获取锁之后才会从调用lock.wait();的位置继续向下执行
						try {
							lock.wait();//t2释放锁进入等待队列等待别的线程调用notify唤醒进入等待队列再被cpu分配执行机会才会继续向下执行
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					
					try {
						TimeUnit.SECONDS.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}, "t1").start();
		
		
	}
}
//关键之处在于 add了size到5之后暂停,别的线程能获取运行机会 并监控到等于5然后继续运行

关键之处在于是t1线程在add的时候,当size等于5了,要能够让t2线程知道size等于5,所以加上了volatile关键字在list保证线程可见性在T1和T2线程。
第二个就是当size等于5的时候能让T1阻塞,让T2立刻去执行wait后面的代码,所以T1调notify只是让T2有机会运行,但是T1不释放锁,T2还是不会运行,所以T1又调用wait释放锁,让T2运行Wait方法之后的。T2运行完结束之前调用notify唤醒T1让其继续运行,如果不调用notify,T1会一直处于wait状态,不会获取到运行机会。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/843202.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号