线程A ,线程B。 线程A 是负责往容器里面放东西,线程B 负责往容器取东西。。要求 线程A 上次放的东西 被取走后才继续放,否则不放。如何实现线程A,B之间高效合作呢?
不使用线程调度时
容器
package cn.hncu.thread.cooperate.v1;
public class Buffer {
private int value;//共享变量
public void put(int i){
value = i;
}
public int get(){
return value;
}
}
线程A
package cn.hncu.thread.cooperate.v1;
public class Sender extends Thread{
private Buffer buf=null;
public Sender(Buffer buf) {
super();
this.buf = buf;
}
@Override
public void run() {
for (int i = 1; i < 6; i++) {
buf.put(i);
System.out.println("Sender put:"+i);
}
}
}
线程B
package cn.hncu.thread.cooperate.v1;
public class Receiver extends Thread {
private Buffer buf=null;
public Receiver(Buffer buf) {
super();
this.buf = buf;
}
@Override
public void run() {
for(int i=1;i<6;i++){
int v = buf.get();
System.out.println("Receiver get:"+v);
}
}
}
演示代码
package cn.hncu.thread.cooperate.v1;
public class Demo {
public static void main(String[] args) {
Buffer buf = new Buffer();
new Sender(buf).start();
new Receiver(buf).start();
}
}
结果
结果是杂乱的,并不是放一次取一次。
解决: 设立一面旗帜,当旗帜立起来的时候,说明A 可以放,旗帜倒下来的时候,说明B 可以取。线程A 放了之后把旗帜放倒。等待 线程B 取 B 取完后 竖起旗帜。唤醒A ,。
修改后 容器代码
package cn.hncu.thread.cooperate.v2;
/**
* 线程协作技术: 互斥 + pv操作(信号量 + notify,wait)
*/
public class Buffer {
private int value;//共享变量
private boolean isEmpty=true; //信号量
public synchronized void put(int i){
while(!isEmpty){
try {
this.wait();
} catch (InterruptedException e) {
}
}
//到达这里,说明信号量为“空”,可以放数据了
value = i;
isEmpty=false;
this.notify();
}
public synchronized int get(){
while(isEmpty){
try {
wait();
} catch (InterruptedException e) {
}
}
//到达这里,说明信号量为“非空”,可以读数据了
isEmpty=true;
notify();
return value;
}
}
其他代码不变,结果