测试类:
package gcc.twoThreadTransData.waitAndNotify;
/**
* 通过wait和notify来实现多线程间的通信,这样可以避免一直轮询的消耗
* wait和notify需要在同步代码块内调用
* 对正在wait的线程执行interrupt(),会报异常,同时释放锁
*
* 1,代码执行到wait,等待执行,并释放锁
* 2,notify所在代码块获取之前wait释放的锁,执行代码块内容
* 3,代码执行到notify,发出唤醒wait的通知,但不立刻释放锁,会先执行完当前程序再释放锁
* 4,wait所在代码块获得锁,wait获得唤醒通知,继续执行wait下面的代码
*/
public class TestThread {
public static void main(String[] args) {
try {
Object lock = new Object();
ThreadB threadB = new ThreadB(lock);
Thread.sleep(50);
threadB.start();
new ThreadA(lock).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
线程B,根据条件X执行等待
package gcc.twoThreadTransData.waitAndNotify;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ThreadB extends Thread {
Object lock;
protected static Logger logger = LoggerFactory.getLogger(ThreadB.class);
public ThreadB(Object lock){
this.lock=lock;
}
@Override
public void run() {
try {
synchronized (lock) {
if (MyList.size()!=5){
logger.info("before wait:"+System.currentTimeMillis());
lock.wait();
// lock.wait(5000);//如果超过5秒没有被唤醒,则自动唤醒
logger.info("after wait:"+System.currentTimeMillis());
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
线程A经过某些操作,条件X改变,在需要的时候唤醒线程B
package gcc.twoThreadTransData.waitAndNotify;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ThreadA extends Thread {
Object lock;
protected static Logger logger = LoggerFactory.getLogger(ThreadA.class);
public ThreadA(Object lock){
this.lock=lock;
}
@Override
public void run() {
try {
synchronized (lock) {
for (int i = 0; i <10 ; i++) {
MyList.add();
if (MyList.size()==5){
logger.info("发送唤醒通知");
lock.notify();
}
logger.info("添加了"+(i+1)+"个元素");
Thread.sleep(500);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
辅助类
package gcc.twoThreadTransData.waitAndNotify;
import java.util.ArrayList;
import java.util.List;
public class MyList {
private static List list = new ArrayList();
public static void add(){
list.add("gcc");
}
public static int size(){
return list.size();
}
}