在一些需要阻塞的业务或者监控来的业务中,我们经常会用到while(true)来进行遍历某一个对象是否存在,如果存在则开启线程去执行某些业务操作。那么如何避免while(true)带来的性能损失呢?
那么,这里我们就用到了线程的等待和通知机制。这里用到了wait()和notify()方法,话不多说直接上代码。
package com.youyou.learn.thread.GuardedSuspension;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class GuardedQueue {
private final Queue<Integer> sourceList;
public GuardedQueue() {
this.sourceList = new LinkedBlockingQueue<>();
}
public synchronized Integer get() {
while (sourceList.isEmpty()) {
try {
// System.out.println("开始等待了");
wait(); // <--- 如果队列为null,等待
// System.out.println("结束等待了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return sourceList.poll();
}
public synchronized void put(Integer e) {
sourceList.add(e);
// System.out.println("通知继续执行");
notifyAll(); //<--- 通知,继续执行 }
}
}
package com.youyou.learn.thread.GuardedSuspension;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class App {
public static void main(String[] args) throws InterruptedException {
GuardedQueue guardedQueue = new GuardedQueue();
ExecutorService executorService = Executors.newFixedThreadPool(3);
Runnable runnable = () -> {
Integer i = guardedQueue.get();
System.out.println(i);
};
executorService.execute(runnable);
executorService.execute(runnable);
executorService.execute(() -> {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
guardedQueue.put(i);
}
}
);
}
}
如果队列是空,程序会在wait处进行等待,当其他线程调用了notifyAll方法后,方法会从wait后面一行代码执行。