多线程实现通讯
我们来做个简单的多线程之间的通讯机制,比如有两个线程,一个线程发送数据,一个线程接受。而让这两个线程
有顺序的执行,不仅要对共享资源上锁,还要用到信号量来实现发送和接受交替。
看下代码实现:
package Test;
public class LockBuffer
{
private int value;
private boolean isEmpty=true;
public synchronized void put(int i)
{
while(!this.isEmpty)
try {this.wait();}
catch (InterruptedException ex) {
}
this.value=i;
this.isEmpty=false;
this.notify();
}
public synchronized int get()
{
while(this.isEmpty)
try {this.wait();}
catch(InterruptedException ex) {}
this.isEmpty=true;
this.notify();
return this.value;
}
public static void main(String args[])
{
LockBuffer buffer= new LockBuffer();
(new SendThread(buffer)).start();
(new ReceiveThread(buffer)).start();
}
}
class SendThread extends Thread{
private LockBuffer buffer;
public SendThread(LockBuffer buffer) {
this.buffer=buffer;
}
public void run() {
for(int i=1;i<5;i++) {
buffer.put(i);
System.out.println(this.getClass().getName()+"put:"+i);
try {
this.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class ReceiveThread extends Thread{
private LockBuffer buffer;
public ReceiveThread(LockBuffer buffer) {
this.buffer=buffer;
}
public void run() {
for(int i=1;i<5;i++) {
System.out.println(this.getClass().getName()+"get:"+buffer.get());
try {
this.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
我们对get和put方法上锁,这样保证同一时间只有一个线程来实现对共享资源value的读或者写。而isEmpty信号量来
保证先执行写线程后执行读线程。加入读线程先执行,当到 while(this.isEmpty) try {this.wait();}线程就会wait阻塞自
己的线程。进入waitting态。然后写线程先写,写完之后改变isEmpty的值。唤醒读线程。这时候写线程不能继续写。
因为isEmpty的值变化了。在执行写会执行wait,进入waitting态。这时候他只能等读线程读完了才能继续写。
这样就实现了读写读写读写。
注意:在控制台输出的时候可能会出现先receive后send的情况,这并不是说读执行在了写的前面。而是因为编译器
在控制台输出的速度远远赶不上线程运算和切换线程的速度,所以可能会出现先读后写的情况。