Java多线程之传统线程同步通信技术

wait和notify实例

子线程循环10次,主线程循环100次。接着子线程循环10次,主线程循环100次。如此循环50次。摘自张孝祥老师线程视频源码。

 

package javaplay.thread.test;

public class TraditionalThreadCommunication {
	public static void main(String[] args) {
		final Business business = new Business();
		new Thread(new Runnable() {

			@Override
			public void run() {
				for (int i = 0; i < 5; i++) {
					business.sub(i);
				}

			}

		}).start();

		for (int i = 0; i < 5; i++) {
			business.main(i);// 此处不能是sub 否则死锁
		}

	}
}

// 经验:要用到共同数据(包括同步锁)或共同算法的若干个方法应该归在同一个类身上,
// 这种设计下好体现了高内聚和程序的健壮性
// 锁是上在代表要操作的资源类的内部方法中(就是下面),而不是线程代码中(就是上面)!!!
// 好处是这个类交给任何一个方法去访问,它天然就同步了
class Business {
	private boolean bShouldSub = true;//volatile???

	// doc:
	// synchronized (obj) {
	// while (<condition does not hold>)
	// obj.wait();
	// ... // Perform action appropriate to condition
	// }
	// .wait必须放在synchronized里面,否则报异常 同步监视器也必须使用同一个
	public synchronized void sub(int i) {
		// 此处用while效果一样,但程序更健壮,因为可避免spurious wakeup, 即别人没叫就醒了(doc)
		if (!bShouldSub) {
			try {
				this.wait();// 进来sub方法时用得就是this作为同步监视器对象 详见doc
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for (int j = 0; j < 1; j++) {
			System.out.println("sub thread sequence of " + j + " ,loop of " + i);
		}
		bShouldSub = false;
		this.notify();// 详见doc
	}

	public synchronized void main(int i) {
		if (bShouldSub) {// 此处用while效果一样,但程序更健壮
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		for (int j = 0; j < 2; j++) {
			System.out.println("main thread sequence of " + j + " ,loop of " + i);
		}
		bShouldSub = true;
		this.notify();
	}
}

 

 

 

 

 

 

 

 

 

 

posted @ 2016-11-18 19:26  john8169  阅读(125)  评论(0编辑  收藏  举报