设计模式 - 阻碍模式模式

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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值