关于java多线程中数据同步问题——共享资源,经常用的是生产者和消费这问题,类似的还有公告板的问题。这里给一个实例。
首先说公告板,只有公告板上有内容,浏览者才能读取内容,如果公告板没有内容,那么必须等待先写入,只有写入了才能读取。
所以应该有三个实体类:
一个是MessageBoard即公告板
Reader 读取
Writer 写入
对于通俗的约定来说,公告板开始时是空的,所以必须先写入信息,这里用一个boolean类型变量表示是否有信息如果没有信息,那么等待写的进程,否则可以读
class MessageBoard{//信息板类
private String message;
private boolean ready = false;//信号灯,起始状态先写后读
public synchronized String read(){//同步的读方法
while (ready == false){//如果不能读取
try{
System.out.println("等待读通知");
wait();//等待,中断当前线程执行,释放对象锁,直到接到唤醒通知
} catch (InterruptedException e) { }
}
ready = false;//设置可以写标志
notify(); //唤醒写线程写数据
return message;
}
public synchronized void write(String s){
while (ready == true){//如果不能写
try{
System.out.println("等待写通知");
wait();//等待,中断当前线程执行,直到接到唤醒通知
}catch (InterruptedException e){ }
}
message = s;//写信息
ready = true;//设置可以读标志
notify();//唤醒读线程进行读取
}
}
class Reader extends Thread{//读信息线程类
private MessageBoard mBoard;
public Reader(MessageBoard m){//保存信息板对象以供run方法使用
mBoard = m;
}
public void run(){//线程体
String s = " ";
boolean reading = true;
while( reading ){
s = mBoard.read();//从信息板对象中读取信息
System.out.println("Reader 读取的信息是: " + s);
try{
sleep(300);//读完一条信息后使当前线程睡眠一段时间
} catch (InterruptedException e) { }
if( s.equals("logoff") ) //如果读到的信息为logoff则结束读取
reading = false;
}
System.out.println("Finished: 等待 5 秒退出...");
try{
sleep( 5000 );//使当前线程睡眠5秒
}catch (InterruptedException e) { }
}
}
private MessageBoard mBoard;
private String messages[ ]= {//要写入信息板对象中的信息
"今天是Monday","明天到哪去?","明天是Sunday,在家休息"};
public Writer(MessageBoard m){//保存信息板对象以供run方法使用
mBoard = m;
}
public void run(){
for (int i = 0; i < messages.length; i++){
mBoard.write(messages[ i ]);//向信息板对象中写入信息
System.out.println("Writer 写入的信息是:" + messages[i] );
try{
sleep((int)(Math.random() * 100));//写完一条信息后使当前线程睡眠一段时间
} catch (InterruptedException e) { }
}
mBoard.write("logoff");//写入结束信息
}
}