Java 多线程例子9 线程之间通信 wait notify notifyAll

下面参照《Java就业培训教材》写了一个相似的线程之间通信的例子,程序实现了一个生产者和一个消费者,还有一个buffer用于存放生产出来的一个对象,buffer中只可以存放一个对象,buffer有一个标志位bFull,如果标志位为true表示buffer里有数值,如果bFull为false表示没有数值。buffer中的对象有两个属性,在多线程中如果不处理同步的话,可能出现属性不对应的情况。

wait:告诉当前线程放弃监视器并进入睡眠状态,直到其他线程进入同一监视器并调用notify为止。

notify:唤醒同一对象监视器中调用wait的第一线程。用于类似饭馆有一个空位子后通知所有等候就餐的顾客中的第一位可以入座的情况。

notifyAll:唤醒同一对象监视器中调用wait的所有线程,具有最高优先级的线程首先被唤醒并执行。用于类似某个不定期的培训班终于招生满额后,通知所有学员都来上课的情况。

从上面明显可以看出wait、notify和notifyAll只能在synchronized方法中调用,记住一个对象的notify只能够唤醒被同一个对象wait的线程。

1,线程不同步

class ThreadDemo {
	public static void main(String[] args) {
		Buffer buf = new Buffer();
		new Producer(buf).start();
		new Consumer(buf).start();
	}
}
class Producer extends Thread {
	private Buffer buf;
	public Producer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		boolean odd = false;
		while(true) {
			if(odd) {
				buf.name="jack";	
				try{Thread.sleep(1000);}catch(Exception e) {}
				buf.sex="female";
			} else {
				buf.name="lucy";	
				try{Thread.sleep(1000);}catch(Exception e) {}
				buf.sex="male";
			}
			odd = !odd;
		}
	}
}
class Consumer extends Thread {
	private Buffer buf;
	public Consumer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		while(true) {
			try{Thread.sleep(1000);}catch(Exception e) {}
			System.out.println(buf.name + " : " + buf.sex);
		}
	}
}
class Buffer {
	boolean bFull;
	String name = "Unkown";
	String sex = "Unkown";
}

 结果 写道

jack : male
jack : female
lucy : female
lucy : female
jack : male
lucy : female
jack : male

 线程不同步回去出现jack : male,lucy : female 这些错误的输出。

2,线程同步

class ThreadDemo {
	public static void main(String[] args) {
		Buffer buf = new Buffer();
		new Producer(buf).start();
		new Consumer(buf).start();
	}
}
class Producer extends Thread {
	private Buffer buf;
	public Producer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		boolean odd = false;
		while(true) {
			synchronized(buf) {
				if(odd) {
					buf.name="jack";	
					try{Thread.sleep(100);}catch(Exception e) {}
					buf.sex="female";
				} else {
					buf.name="lucy";	
					try{Thread.sleep(100);}catch(Exception e) {}
					buf.sex="male";
				}
			}
			odd = !odd;
		}
	}
}
class Consumer extends Thread {
	private Buffer buf;
	public Consumer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		while(true) {
			synchronized(buf) {
				try{Thread.sleep(100);}catch(Exception e) {}
				System.out.println(buf.name + " : " + buf.sex);
			}
		}
	}
}
class Buffer {
	boolean bFull;
	String name = "Unkown";
	String sex = "Unkown";
}

 

结果 写道
Unkown : Unkown
lucy : male
jack : female
lucy : male
jack : female
lucy : male

 没有采用线程通信会出现Unkown : Unkown 和连续输出lucy和jack的情况。

3,线程通信 wait notify

class ThreadDemo {
	public static void main(String[] args) {
		Buffer buf = new Buffer();
		new Producer(buf).start();
		new Consumer(buf).start();
	}
}
class Producer extends Thread {
	private Buffer buf;
	public Producer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		boolean odd = false;
		while(true) {
			synchronized(buf) {
				if(buf.bFull)
					try{buf.wait();}catch(Exception e) {}
				if(odd) {
					buf.name="jack";	
					try{Thread.sleep(100);}catch(Exception e) {}
					buf.sex="female";
				} else {
					buf.name="lucy";	
					try{Thread.sleep(100);}catch(Exception e) {}
					buf.sex="male";
				}
				buf.bFull = true;
				buf.notify();
			}
			odd = !odd;
		}
	}
}
class Consumer extends Thread {
	private Buffer buf;
	public Consumer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		while(true) {
			synchronized(buf) {
				if(!buf.bFull)
					try{buf.wait();}catch(Exception e) {}
				//try{Thread.sleep(100);}catch(Exception e) {}
				System.out.println(buf.name + " : " + buf.sex);
				buf.bFull = false;
				buf.notify();
			}
		}
	}
}
class Buffer {
	boolean bFull = false;
	String name = "Unkown";
	String sex = "Unkown";
}

 

结果 写道
lucy : male
jack : female
lucy : male
jack : female
lucy : male
jack : female

 

结果达到了预期的目的。

4,面前对象 同步函数

class ThreadDemo {
	public static void main(String[] args) {
		Buffer buf = new Buffer();
		new Producer(buf).start();
		new Consumer(buf).start();
	}
}
class Producer extends Thread {
	private Buffer buf;
	public Producer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		boolean odd = false;
		while(true) {
			if(odd) {
				buf.put("jack","female");
			} else {
				buf.put("lucy","male");
			}
			odd = !odd;
		}
	}
}
class Consumer extends Thread {
	private Buffer buf;
	public Consumer(Buffer buf) {
		this.buf = buf;
	}
	public void run() {
		while(true) {
			buf.get();
		}
	}
}
class Buffer {
	private boolean bFull = false;
	private String name = "Unkown";
	private String sex = "Unkown";
	
	public synchronized void put(String name, String sex) {
		if(bFull)
			try{wait();}catch(Exception e) {}
		this.name = name;
		this.sex = sex;
		bFull = true;
		notify();
	}
	public synchronized void get() {
		if(!bFull)
			try{wait();}catch(Exception e) {}
		System.out.println(name + " : " + sex);
		bFull = false;
		notify();
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值