您的位置:首页 > 编程语言 > Java开发

线程等待唤醒机制

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 线程