java wait/notify 面试题

下面例子使用wait/notify 实现:

public class WaitNotifyExample {
	private volatile static List list = new ArrayList<>();

	public void add() {
		list.add("aa");
	}

	public int size() {
		return list.size();
	}

	public static void main(String[] args) {
		final WaitNotifyExample example = new WaitNotifyExample();

		Thread t1 = new Thread(new Runnable() {

			@Override
			public void run() {

				for (int i = 0; i < 10; i++) {
					example.add();
					System.err.println("当前线程:" + Thread.currentThread().getName() + "添加了一个 元素");
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

			}
		}, "t1");

		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {

				while (true) {
					if (example.size() == 5) {
						System.err.println("当前线程:" + Thread.currentThread().getName() 
+ " list size = 5 线程停止");
						throw new RuntimeException();

					}
				}

			}
		}, "t2");
		t1.start();
		t2.start();
	}
}

1.使用wait/notify 实现

public class WaitNotifyExample {
	private volatile static List list = new ArrayList<>();

	public void add() {
		list.add("aa");
	}

	public int size() {
		return list.size();
	}

	public static void main(String[] args) {
		final WaitNotifyExample example = new WaitNotifyExample();

		final Object lock = new Object();
		Thread t1 = new Thread(new Runnable() {

			@Override
			public void run() {

				synchronized (lock) {
					for (int i = 0; i < 10; i++) {
						example.add();
						System.err.println("当前线程:" + Thread.currentThread().getName() + 
"添加了一个 元素");
						try {
							Thread.sleep(500);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						if (example.size() == 5) {
							System.err.println("已发出通知");
							lock.notify();
						}
					}
				}
			}
		}, "t1");

		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (lock) {
					if (example.size() != 5) {
						try {
							lock.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					System.err.println("当前线程:" + Thread.currentThread().getName() + 
" list size = 5 线程停止");
					throw new RuntimeException();
				}
			}
		}, "t2");
		t1.start();
		t2.start();
	}
}


结果:

java wait/notify 面试题_第1张图片

线程t1 notify后并没有释放锁,等元素添加完成后,t2才开始执行,所以此方法不是实时通知。


使用wait/nofify 方法实现线程间的通信,

  1. wait 和 notify 必须配合 synchronized 关键字使用
  2. wait方法释放锁,notify 方法不释放锁


2. 使用CountDownLatch 实现实时通知:

public class WaitNotifyExample {
	private volatile static List list = new ArrayList<>();

	public void add() {
		list.add("aa");
	}

	public int size() {
		return list.size();
	}

	public static void main(String[] args) {
		final WaitNotifyExample example = new WaitNotifyExample();

		final CountDownLatch cdl = new CountDownLatch(1);
		Thread t1 = new Thread(new Runnable() {

			@Override
			public void run() {

				for (int i = 0; i < 10; i++) {
					example.add();
					System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个 元素");
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (example.size() == 5) {
						System.err.println("已发出通知");
						cdl.countDown();
					}
				}
			}
		}, "t1");

		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				if (example.size() != 5) {
					try {
						cdl.await();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println("当前线程:" + Thread.currentThread().getName() + " list size = 5 线程停止");
				throw new RuntimeException();
			}
		}, "t2");
		t1.start();
		t2.start();
	}
}

结果:

java wait/notify 面试题_第2张图片

你可能感兴趣的:(java)