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

Java多线程知识点总结——进阶篇(七) 之 等待唤醒机制

2018-03-31 15:47 645 查看
1、线程的通信方式通信:

其实就是多个线程在操作同一个资源,但是操作的动作不同。

2、API介绍

Object.wait():在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。

Object.notify():唤醒在此对象监视器上等待的单个线程。

Object.notifyAll():唤醒在此对象监视器上等待的所有线程。

先来实现一个需求:

有两个线程,一个往资源池中生产数据,一个从资源池中消费数据

代码如下:

class Res {
private String name;
private String sex;
private boolean flag = false; //用来判断有没有数据

/**
* 生产一条数据
* @param name
* @param sex
*/
public synchronized void set(String name, String sex) {
if (flag)
try {this.wait();} catch (Exception e) {}

this.name = name;
this.sex = sex;
flag = true;
this.notify(); //唤醒另一个线程
}

/**
* 消费数据
*/
public synchronized void out() {
if (!flag)
try {this.wait();} catch (Exception e) {}

System.out.println(name + "........" + sex);
flag = false;
this.notify();
}
}

class Input implements Runnable {
private Res r;

Input(Res r) {
this.r = r;
}
public void run() {
int x = 0;
while (true) {

4000
if (x == 0)
r.set("mike", "man");
else
r.set("丽丽", "女女女女女");
x = (x + 1) % 2;
}
}
}

class Output implements Runnable {
private Res r;

Output(Res r) {
this.r = r;
}

public void run() {
while (true) {
r.out();
}
}
}

class InputOutputDemo2 {
public static void main(String[] args) {
Res r = new Res();

new Thread(new Input(r)).start();
new Thread(new Output(r)).start();
}
}


上面再生产和消费都是单线程的情况下是没有问题的,但是如果变成了两个生产者和两个消费者,且该资源池只能存放一条数据,那么上面代码就需要修改了。

第一点:需要将上面代码的 notify() 改成 notifyAll()。因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。

第二点:需要将

if (flag)
try {this.wait();} catch (Exception e) {}


改成:

while(flag)
try {this.wait();} catch (Exception e) {}


原因:让被唤醒的线程再一次判断标记。

多线程版本的完整代码如下:

class ProducerConsumerDemo {
public static void main(String[] args) {
Resource r = new Resource();

Producer pro = new Producer(r);
Consumer con = new Consumer(r);

new Thread(pro).start();
new Thread(pro).start();
new Thread(con).start();
new Thread(con).start();

}
}

class Resource {
private String name;
private int count = 1;
private boolean flag = false;

// t1 t2
public synchronized void set(String name) {
while (flag)
try {this.wait();} catch (Exception e) {}// t1(放弃资格) t2(获取资格)
this.name = name + "--" + count++;

System.out.println(Thread.currentThread().getName() + "...生产者.." + this.name);
flag = true;
this.notifyAll();
}

// t3 t4
public synchronized void out() {
while (!flag)
try {wait();} catch (Exception e) {}// t3(放弃资格) t4(放弃资格)
System.out.println(Thread.currentThread().getName() + "...消费者........." + this.name);
flag = false;
this.notifyAll();
}
}

class Producer implements Runnable {
private Resource res;

Producer(Resource res) {
this.res = res;
}

public void run() {
while (true) {
res.set("+商品+");
}
}
}

class Consumer implements Runnable {
private Resource res;

Consumer(Resource res) {
this.res = res;
}

public void run() {
while (true) {
res.out();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐