Balking 模式:
当一个线程尝试执行某个操作时,它首先会检查一个条件(通常是某个状态或标志位),判断这个操作是否已经被其他线程完成,或者当前对象的状态是否不适合执行此操作。
如果操作已被完成或条件不满足: 线程会“犹豫”或“退避”,立即放弃执行该操作并返回,而不会等待条件改变或尝试重复执行。
如果操作未被完成且条件满足: 线程才会执行该操作,并可能改变状态以表明操作已完成。
核心特点:
条件检查优先: 在执行实际操作前,必须先检查一个“守卫条件”(Guard Condition)。
立即返回/放弃: 如果守卫条件表明操作不应进行(例如,已经做过、对象状态不合适),则调用立即返回,不做任何等待。这是它与“保护性暂停”(Guarded Suspension)模式的关键区别,后者在条件不满足时会等待。
避免重复或不必要的操作: 主要目的是提高效率,避免不必要的计算或资源竞争。
线程安全: 守卫条件的检查和后续可能的状态修改通常需要是原子操作,因此经常会使用 synchronized 关键字或 volatile 变量配合原子类来实现。
package org.example;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TwoStageStop {
public static void main(String[] args) throws InterruptedException {
TwoStageStop twoStageStop = new TwoStageStop();
twoStageStop.start();
twoStageStop.start();
twoStageStop.start();
Thread.sleep(5000);
twoStageStop.stop();
}
private Thread monitorThread;
private volatile boolean stop = false;
private boolean started = false;
public void start() {
synchronized (this) {
if(started) {
return;
}
started = true;
}
monitorThread = new Thread(()->{
while (true) {
if(stop) {
log.info("料理后事");
break;
}
try {
Thread.sleep(1000);
log.info("执行监控流程");
}catch (InterruptedException e){
}
}
},"monitor");
monitorThread.start();
}
public void stop(){
stop = true;
monitorThread.interrupt();
}
}
应用场景
保证幂等性