您的位置:首页 > 编程语言 > Java开发

用java来实现线程之间的wait、notify()通信

2015-09-28 10:46 597 查看
两个线程一个为Input向资源中写入数据,一个为output从资源中读取数据。当写入线程写入数据的时候,首先要对资源加锁,如果资源中没有数据,则向资源中写入数据,写入完毕后释放锁(notify),如果资源有数据,则等待,直到资源中没有数据为止才继续写入数据。

特别需要注意的的写入线程中标红的部分,else不能加上。因为两个线程都在操作同一个资源,r.isflag()为true判断完毕后,判断完毕后,r.flag可能已经为false。此时会出现与要求不符的情况。

public void run() {

int x = 0;

while (true) {



synchronized (r) {

if (r.isFlag())//如果已经有数据

{

try {

r.wait();//已经阻塞线程了 阻塞之后 肯定为f.flag一定为false

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}else{//如果加上else,那么会出现一种情况if判断时为true,判断完毕后,r.flag已经为false。

//会出现数据不一致的情况 因此不需要加else

if (x % 2 == 0) {

r.setName("类兴邦");

r.setSex("男");

}else

{

r.setName("张红");

r.setSex("女");

}

x=++x%2;

r.setFlag(true);

r.notify();//通知其他获取对象锁的线程

}

}

}

}

正确的代码如下:

package WN;

public class Input extends Thread {
	private Res r;

	public Input(Res r) {
		this.r = r;
	}

	@Override
	public void run() {
		int x = 0;
	
		while (true) {

		
			synchronized (r) {
				if (r.isFlag())//如果已经有数据
				{
					try {
						r.wait();//已经阻塞线程了 阻塞之后 肯定为f.flag一定为false
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}//如果加上else,那么会出现一种情况if判断时为true,判断完毕后,r.flag已经为false。
				//会出现数据不一致的情况 因此不需要加else
					if (x % 2 == 0) {
                        r.setName("类兴邦");
                        r.setSex("男");
					}else
					{
						r.setName("张红");
						r.setSex("女");
					}
					x=++x%2;
					r.setFlag(true);
					r.notify();//通知其他获取对象锁的线程
				}
			
					
			
		}
	}
public static void main(String[] args) {
	Res r = new Res();
	Input in = new Input(r);
	
	Output out = new Output(r);
	in.start();
	out.start();
	
	
}
}


package WN;

public class Res {
	private String name;
	private String sex;
	private boolean flag=false;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public boolean isFlag() {
		return flag;
	}
	public void setFlag(boolean flag) {
		this.flag = flag;
	}

}


package WN;

public class Output extends Thread{
	private Res r;

	public Output (Res r) {
		this.r = r;
	}

	@Override
	public void run() {
		int x = 0;
		while (true) {

	
			synchronized (r) {
				if (r.isFlag())//如果已经有数据
				{
					System.out.println(r.getName()+","+r.getSex());
					r.setFlag(false);//已经取出数据
					r.notify();
				}else//没有数据
				{
					try {
						r.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
					
			}
		}
	}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: