Java 多线程之间通信

背景

之所以要用到java的多线程,是因为最近写的程序需要一个这样的场景:server端监听在一个IO上,但是client端有2个IO(可以是多个,我这里是2个都需要跟server的那个IO通信,但是client两个IO并不是同时向server的那个IO发/收消息。
所以需要用到java的多线程,为client每一个IO的通信过程都建立一个线程。一行一行地读文件中的收发顺序,当IO1发/收消息的时候,IO2就等待,当IO2发/收消息的时候IO1就等待。当通信完成后就关闭该子线程。

Synchronized,wait(), notify()

synchronized是java中用于解决并发情况下数据同步访问的一个很重要的关键字。当我们想要保证一个共享资源在同一时间只会被一个线程访问时,我们就可以在代码中使用synchronized关键字对类或者对象加锁。我这里用到的是给对象加锁。
synchronized修饰的代码,在开始执行时就会加锁,执行完成后会进行解锁。代码如下:

public class SyncThread extends Thread{
    threadTOGO lock = new threadTOGO;
    Thread A = new Thread(new Runnable() {
	    @Override
	    public void run() {
	        synchronized(lock){
	             try {
	             	for(int index = 0; index < messageCount; index++)  {
	             		while(lock.IO==2)
	                	lock.wait();                 //交出锁的控制权,进入wait状态
	             	   *do something here;*
	             	    if(start to run thread B) {
	             			lock.IO = 2;
	             			lock.notify();               //唤醒正在wait的线程B
	             		}
	             	}
	             	
	             }catch(Exception ex) {
	             		ex.printStackTrace();
				  }finally {
				      	lock.IO = 2;                 //防止死锁
				        lock.notify();
				  }
	         }
    	}
	});
	Thread B = new Thread(new Runnable() {
	    @Override
	    public void run() {
	        synchronized(lock){
	             try {
	                for(int index = 0; index < messageCount; index++)  {
	                	while(lock.IO==1)
	                		lock.wait();
	             		*do something here;*
	             		if(start to run thread A) {
	             			lock.IO = 1;
	             			lock.notify();
	             		}
	                }            	
	             }catch(Exception ex) {
	             		ex.printStackTrace();
				  }finally {
				      	lock.IO = 1;
				        lock.notify();
				  }
	         }
    	}
	});
}  
class threadTOGO{                                   //锁对象
    int IO=1;
}   

需要注意的是:想要执行某个对象的notify(), notifyAll(),wait(), wait(long), wait(long, int)方法就必须获取该对象的锁,需要使用synchronized,不然就会抛出IllegalMonitorStateException异常。
在执行这段代码的时候,出现过一种死锁的情况:即当线程A因为某种特殊原因在还没有运行到for循环中的notify()的时候就中止了,这个时候线程B还处于wait状态没有被唤醒,而主线程也在等待着线程A和线程B都运行完了执行下一步操作。所以为了防止这种死锁的情况,我在finally中都加了个notify(),这样即使没有执行到for循环中的notify(),也会执行finally中的notify().

这样就实现了一个简单的线程同步啦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值