同步设计模式之Balking(犹豫)
- Balking用于一个线程或本线程发现另一个线程已经做完了相同的事情,那么本线程就不用重复做该事情了
@Slf4j(topic = "c.TwoPhaseTermination")
public class Test13 {
public static void main(String[] args) throws InterruptedException {
TwoPhaseTermination tpt = new TwoPhaseTermination();
tpt.start();
tpt.start();
Thread.sleep(3500);
tpt.stop();
}
}
@Slf4j(topic = "c.TwoPhaseTermination")
class TwoPhaseTermination {
private Thread monitorThread;
private volatile boolean stop = false;
public void start() {
monitorThread = new Thread(() -> {
while (true) {
Thread current = Thread.currentThread();
if (stop) {
log.debug("料理后事");
break;
}
try {
Thread.sleep(1000);
log.debug("执行监控记录");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "monitor");
monitorThread.start();
starting = true;
}
public void stop() {
stop = true;
monitorThread.interrupt();
}
}
- 上面的代码,监控线程有一个就行了,但是如果同时调用多次start方法,会创建多个线程,没有必要,因此可以增加一个变量starting用于表示start方法是否执行了,同时使用synchronized来保证原子性
@Slf4j(topic = "c.TwoPhaseTermination")
public class Test13 {
public static void main(String[] args) throws InterruptedException {
TwoPhaseTermination tpt = new TwoPhaseTermination();
tpt.start();
tpt.start();
Thread.sleep(3500);
tpt.stop();
}
}
@Slf4j(topic = "c.TwoPhaseTermination")
class TwoPhaseTermination {
private Thread monitorThread;
private volatile boolean stop = false;
private boolean starting = false;
public void start() {
synchronized (this) {
if (starting) {
return;
}
starting = true;
}
monitorThread = new Thread(() -> {
while (true) {
Thread current = Thread.currentThread();
if (stop) {
log.debug("料理后事");
break;
}
try {
Thread.sleep(1000);
log.debug("执行监控记录");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "monitor");
monitorThread.start();
}
public void stop() {
stop = true;
monitorThread.interrupt();
}
}
- 应用:实现线程安全的单例