前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java多线程通信lock和wait

Java多线程通信lock和wait

作者头像
付威
发布2020-01-21 17:15:57
7720
发布2020-01-21 17:15:57
举报

在Java多线程中有一对配合使用过的两个方法,来实现线程间通信的功能–lock和wait, 由于这个需要获得锁,所以必须结合synchronized一起使用。首先我们先看一个例子:

  public class LockWait {
	
	static volatile List<String> itemContainer = new ArrayList<>();
	static Object obj = new Object();
	
	public static void main(String[] args) {
		Thread th1 = new Thread(() -> {
			synchronized (obj) {
				for (int i = 0; i < 10; i++) {
					System.out.println("th1添加元素");
					itemContainer.add(String.valueOf(i));
					if (itemContainer.size() == 5) {
						System.out.println("th1线程发出通知");
						obj.notify();
					}
				}
			}
		});
		
		Thread th2 = new Thread(() -> {
			synchronized (obj) {
				System.out.println("进入th2线程");
				if (itemContainer.size() != 5) {
					try {
						System.out.println("th2线程开始等待");
						obj.wait();
						System.out.println("th2线程等待结束");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("th2线程结束");
				}
			}
			
		});
		
		th2.start();
		th1.start();
	}
}

输出结果如下:

进入th2线程
th2线程开始等待
th1添加元素
th1添加元素
th1添加元素
th1添加元素
th1添加元素
th1线程发出通知
th1添加元素
th1添加元素
th1添加元素
th1添加元素
th1添加元素
th2线程等待结束
th2线程结束

具体运行逻辑如下:

Java多线程通信lock和wait
Java多线程通信lock和wait

总结上面的运行结果,th2在wait的时候,th1可以持有锁。说明wait是释放锁,而notify不释放锁。

这样也就带来了一个弊端,无法实时的得到结果,就是说当List达到我们想要的结果的时候,th1线程一直还在持有锁,导致th2无法执行。

有没有更好办法呢?在Java中提供了一个CountDownLatch类:

public class CountDownLatchTest {
	
	public static void main(String[] args) {
		final List<String> itemContainer = new ArrayList<>();
		final CountDownLatch countDownLanch = new CountDownLatch(1);
		Thread th1 = new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				try {
					System.out.println("th1添加元素");
					itemContainer.add(String.valueOf(i));
					if (itemContainer.size() == 5) {
						System.out.println("th1线程发出通知");
						countDownLanch.countDown();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		});
		
		Thread th2 = new Thread(() -> {
			System.out.println("进入th2线程");
			if (itemContainer.size() != 5) {
				try {
					System.out.println("th2线程开始等待");
					countDownLanch.await();
					System.out.println("th2线程等待结束");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("th2线程结束");
			}
			
		});
		
		th2.start();
		
		th1.start();
	}
}

运行结果:

进入th2线程
th1添加元素
th2线程开始等待
th1添加元素
th1添加元素
th1添加元素
th1添加元素
th1线程发出通知
th1添加元素
th2线程等待结束
th1添加元素
th2线程结束
th1添加元素
th1添加元素
th1添加元素
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-12-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档