1. 简介
- 如果某个对象处于不完整或不适当的状态,则阻止该对象执行某个代码。
- 使用阻塞模式,只有当对象处于特定状态时,才会执行特定代码。
- 阻挡模式是一种软件设计模式,它仅在对象处于特定状态时对对象执行操作。例如,如果一个对象读取ZIP文件,并且当ZIP文件未打开时调用>方法调用该对象上的get方法,则该对象将在请求时“阻止”。
2. 例子
洗衣机上有一个启动按钮来启动洗衣。当洗衣机处于非活动状态时,按钮按预期工作,但如果已经在洗衣,则按钮不执行任何操作
3. 代码说明
- 在这个示例实现中,“WashingMachine”是一个具有两种状态的对象:启用和清洗。如果机器已启用,状态将更改为使用线程安全方法进行清洗。另一方面,如果它已经在清洗,并且任何其他线程执行’wash()’,它将不会执行该操作,并且会返回而不执行任何操作。
4. 类结构图
5. 代码运行
在这里插入代码片
package com.study121_blacking;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
在阻碍设计模式中,
如果对象的方法在不适当的状态下被调用,
那么该方法将返回而不做任何事情。使用此模式的对象通常仅处于一种状态,
该状态易于暂时停止,但时间未知
<p>在这个示例实现中,{@link WashingMachine}是一个具有两种状态的对象:启用和清洗。
如果机器已启用,状态将更改为使用线程安全方法进行清洗。另一方面,如果它已经在清洗,
并且任何其他线程执行{@link WashingMachinewash()},
它将不会执行该操作,并且会返回而不执行任何操作。
*/
public class App {
public static void main(String[] args) {
final var washingMachine = new WashingMachine();
var executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 3; i++) {
executorService.execute(washingMachine::wash);
}
executorService.shutdown();
try {
if(!executorService.awaitTermination(10, TimeUnit.MILLISECONDS)){
executorService.shutdown();
}
}catch (InterruptedException e){
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}
6. 运行结果
pool-1-thread-1现在机器状态null
pool-1-thread-3现在机器状态WASHING
如果机器已经清洗过,则无法清洗!
pool-1-thread-2现在机器状态WASHING
如果机器已经清洗过,则无法清洗!
pool-1-thread-1正在清洗
pool-1-thread-1清洗完成
7. 实现
package com.study121_blacking;
import java.util.concurrent.TimeUnit;
/**
在执行某些工作时模拟延迟的接口
*/
public interface DelayProvider {
void executeAfterDelay(long interval, TimeUnit timeUnit, Runnable task);
}
package com.study121_blacking;
import java.util.concurrent.TimeUnit;
public class WashingMachine implements DelayProvider{
//private final DelayProvider delayProvider;
private WashingMachineState washingMachineState;
public WashingMachine(WashingMachineState washingMachineState) {
this.washingMachineState = washingMachineState;
}
// 创建洗衣机的新实例
public WashingMachine() {
}
// public WashingMachine() {
// this((interval, timeUnit, task) -> {
// try {
// Thread.sleep(timeUnit.toMillis(interval));
// } catch (InterruptedException ie) {
// Thread.currentThread().interrupt();
// }
// task.run();
// });
// }
public WashingMachineState getWashingMachineState() {
return washingMachineState;
}
/**
* @Description 如果物体处于适当状态,则负责清洗的方法。
*/
public void wash(){
synchronized (this){
var machineState = getWashingMachineState();
System.out.println(Thread.currentThread().getName()+"现在机器状态"+machineState);
if(this.washingMachineState == WashingMachineState.WASHING){
System.out.println("如果机器已经清洗过,则无法清洗!");
return;
}
this.washingMachineState = WashingMachineState.WASHING;
}
System.out.println(Thread.currentThread().getName()+"正在清洗");
executeAfterDelay(50, TimeUnit.MILLISECONDS,this::endOfWashing);
}
//通过改变机器状态来结束清洗的方法
public synchronized void endOfWashing(){
washingMachineState = WashingMachineState.ENABLED;
System.out.println(Thread.currentThread().getName()+"清洗完成");
}
@Override
public void executeAfterDelay(long interval, TimeUnit timeUnit, Runnable task) {
try {
Thread.sleep(timeUnit.toMillis(interval));
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
task.run();
}
}
package com.study121_blacking;
//WashingMachineState枚举描述机器处于何种状态,它可以启用并准备好工作,以及在清洗过程中。
public enum WashingMachineState {
ENABLED, WASHING;
}