返回目录
在java中,Object对象有两个方法:.wait() 和 .notify(),wait用户阻塞线程,notify用于唤醒线程。
注意:wait和notify必须用在synchronized代码块中,否则抛出异常。
看一道练习题吧:要求用两个线程,主线程打印1至10,然后子线程打印1至5,然后主线程又打印1至10,子线程打印1至5,如此循环50次,写出代码实现。
package com.jsunw; import com.sun.xml.internal.bind.v2.TODO; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * <p>类说明</p> * * @author Sun Wang * @date 2015/12/4 */ public class Test { public static void main(String[] args) { final Outputer outputer = new Outputer(); //开启一个主线程 new Thread(new Runnable() { @Override public void run() { for(int i = 0; i < 50; i++) { outputer.main(i); } } }).start(); //开启一个子线程 new Thread(new Runnable() { @Override public void run() { for(int i = 0; i < 50; i++) { outputer.sub(i); } } }).start(); } } class Outputer { //是否应该执行子线程,用于防止线程的虚假唤醒 private boolean bShouldSub = false; public synchronized void main(int loop) { try { while(bShouldSub) { //执行子线程时,阻塞主线程 this.wait(); } //某一轮打印 for(int i = 0; i < 10; i++) { System.out.println("main : " + i + " loop of " + loop); } //主线程执行完毕后修改标识 bShouldSub = true; //唤醒其他阻塞线程中的一个,这里指子线程 this.notify(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void sub(int loop) { try { while(!bShouldSub) { //执行主线程时,阻塞子线程 this.wait(); } //某一轮打印 for(int i = 0; i < 5; i++) { System.out.println("sub : " + i + " loop of " + loop); } //子线程执行完毕后修改标识 bShouldSub = false; //唤醒其他阻塞线程中的一个,这里指主线程 this.notify(); } catch (InterruptedException e) { e.printStackTrace(); } } }
下一篇:ThreadLocal