直接看代码:
package com.mjlf.myBatis.thread;
/**
* Created by a123 on 17/2/18.
* 一对一生产者消费者
*/
public class PC {
private String value = "";
class P {
private PC lock;
public P(PC lock) {
super();
this.lock = lock;
}
public void create() {
try {
synchronized (this.lock) {
// Thread.sleep(1000);
while (!"".equals(value)) {
this.lock.wait();
}
System.out.println(Thread.currentThread().getName() + " : create");
value = "create";
this.lock.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class C {
private PC lock;
public C(PC lock) {
super();
this.lock = lock;
}
public void direc() {
try {
synchronized (this.lock) {
// Thread.sleep(1000);
while ("".equals(value)) {
this.lock.wait();
}
System.out.println(Thread.currentThread().getName() + " : direc");
value = "";
this.lock.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThreadP implements Runnable {
private P p;
public ThreadP(P p) {
this.p = p;
}
public void run() {
while (true) {
this.p.create();
}
}
}
class ThreadC implements Runnable {
private C c;
public ThreadC(C c) {
this.c = c;
}
public void run() {
while (true) {
this.c.direc();
}
}
}
public static void main(String[] args){
PC pc = new PC();
P p = pc.new P(pc);
C c = pc.new C(pc);
Thread[] threadP = new Thread[2];
Thread[] threadC = new Thread[2];
for(int i = 0; i < threadC.length; i++){
threadC[i] = new Thread(pc.new ThreadP(p));
threadP[i] = new Thread(pc.new ThreadC(c));
threadC[i].setName("C" + i);
threadP[i].setName("P" + i);
threadC[i].start();
threadP[i].start();
}
}
}
/**
C0 : create
P0 : direc
C0 : create
P0 : direc
C1 : create
P0 : direc
C1 : create
*/
解释:以上代码存在几个注意点:
1. 首先看过看过我1对1生产者消费者的会知道, while (!”“.equals(value)) 这个地方以前使用的是if做判断,但是这样有一个问题, 就是可能会出现多次连续生产或多次连续消费的问题, 这不是我想要的结果,所以可以使用while循环判断解决这个问题
2. 其次, 以上代码可能会出现消费者唤醒消费者、生产者唤醒生产者的现象,因为notify是随机唤醒的。为了解决这问题, 可以使用notifyAll方法唤醒所有的线程