在java多线程中,等待唤醒机制是最经典的也是最能够体现java多线程中的线程安全的问题,在写等待唤醒机制的时候,我们要先去了解什么是等待唤醒机制
等待唤醒机制就是指在多个线程进行并发的去操作同一个资源的问题,
以生产馒头和消费馒头举例;就比如我们有一个容器(resource,代表的是馒头的存放),这里面设置的是两个变量,i(表示的是馒头的数量)和name(表示的是馒头这个名字),线程0和线程1是生产馒头的线程,线程2和线程3是消费馒头的线程。在线程0或线程1进行生产馒头之后,线程2或者线程3就接着去消费这个馒头
由上图可知,在生产者消费者中,我们要去定义一个公共的资源,Resource,这四个线程都去共享这个资源。
代码如下
package java多线程;
/*
* java的等待/唤醒机制
* 生产者/消费者的问题:多生产者多消费者的问题
*/
//定义的是资源
class AResource {
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set1(String name) {
while (flag) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.name = name;
count++;
flag = true;
notifyAll();
System.out.println(Thread.currentThread().getName() + "....生产者..." + this.name + this.count);
}
public synchronized void eat() {
// while是解决每一次启动线程都要去判断标记的方式
while (!flag) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "....消费者..." + this.count);
flag = false;
notifyAll();
// 这个方法是为了方式线程死锁的问题
}
}
// 定义生产者
class Producer implements Runnable {
private AResource ar;
public Producer(AResource ar) {
this.ar = ar;
}
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
ar.set1("馒头");
}
}
}
// 定义消费者
class Consumer implements Runnable {
private AResource ar;
public Consumer(AResource ar) {
// TODO Auto-generated constructor stub
this.ar = ar;
}
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
ar.eat();
}
}
}
public class ProducerConsumerExample {
public static void main(String[] args) {
AResource ar = new AResource();
// 这个表示的是生产者的任务
Producer pr = new Producer(ar);
// 这个表示的是消费者的任务
Consumer con = new Consumer(ar);
new Thread(pr).start();
new Thread(pr).start();// 两个生产者的线程,其实是一个生产者的任务
new Thread(con).start();
new Thread(con).start();// 两个消费者的线程,其实是一个消费者的任务
}
}
总结:好好的复习自己基础是很重要的啊,基础就是技术的基石!!!