返回目录
在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




