线程等待唤醒机制
2016-04-07 10:36
441 查看
线程等待唤醒机制
1、问题描述
有一个Person资源对象,InputDataThread是对其进行赋值操作的线程,OutputDataThread是对其进行取值输出打印操作线程。现在要求,InputDataThread赋值一次,OutputDataThread就打印输出一次,一一对应。java中通过使用wait和notify/notifyAll方法来实现等待唤醒机制。2、代码展示
person资源Code/** * Person是线程共享资源对象 * @author xuyi3 * @2016年4月7日 @上午10:08:59 * @Person * @功能说明:<br> * 春风十里不如你 */ public class Person { /** 名字*/ private String name; /** 性别*/ private String sex; /** 是否有数据(标识符)*/ private boolean haveData = false; //省略setter 和 getter 方法 }
InputDataThread赋值线程Code
/** * @author xuyi3 * @2016年4月7日 @上午9:12:47 * @InputDataThread * @功能说明:给person赋值的操作线程 * 春风十里不如你 */ public class InputDataThread implements Runnable { // 线程共享操作资源person对象 private Person person; public InputDataThread(Person person) { this.person = person; } @Override public void run() { boolean flag = true; while (true) { synchronized (person) { if (person.isHaveData()) {// 如果person对象已经有数据那么就wait()操作 try { person.wait();//当前线程等待 } catch (InterruptedException e) { e.printStackTrace(); } } else {// 如果person对象还没有数据就赋值操作 if (flag) { person.setName("徐义"); person.setSex("男"); flag = false; } else { person.setName("吴冉冉"); person.setSex("女"); flag = true; } person.setHaveData(true);// 设置person对象已有数据 person.notify();// 唤醒持有person对象的线程 } } } } }
OutputDataThread输出打印Code
/** * @author xuyi3 * @2016年4月7日 @上午9:17:57 * @OutputDataThread * @功能说明:输出打印操作线程<br> * 春风十里不如你 */ public class OutputDataThread implements Runnable { // 线程共享操作资源person对象 private Person person; public OutputDataThread(Person person) { this.person = person; } @Override public void run() { while (true) { synchronized (person) { if (!person.isHaveData()) {// 如果person对象没有数据输出打印线程就wait() try { person.wait();//当前线程等待 } catch (InterruptedException e) { e.printStackTrace(); } } else {// 如果person对象已经有数据了,输出打印线程就打印数据 System.out.println( person.getName() + "==>" + person.getSex()); person.setHaveData(false);// 打印完之后设置person对象没有数据了 person.notify();// 唤醒持有person对象的线程 } } } } }
APPMain Code
public class AppMain { public static void main(String[] args) { // 线程共享操作资源 Person person = new Person(); //赋值线程 InputDataThread inputDataThread = new InputDataThread(person); //输出打印线程 OutputDataThread outputDataThread = new OutputDataThread(person); // 启动两个线程 new Thread(inputDataThread).start(); new Thread(outputDataThread).start(); } }
解释说明
重点只有当多个线程对共享资源进行操作的时候才会出现线程安全问题,解决线程安全问题的第一思路应该是找出共享资源对共享资源进行同步操作,即多个线程是持有的锁应该是同一个Object的,否则就无法控制线程安全。上面示例当中Person对象就是两个线程的共享资源。上面示例其实就是生产者消费者模型(一个生产者和一个消费者模型),wait()、notify()、notifyAll()这些方法,只能在持有锁对象里才能使用否则会报错(IllegalMonitorStateException)。线程等待唤醒机制使用不恰当就会产生死锁。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树