多线程设计模式之四 终止模式Blacking

需求来源

终止模式就是说,比如有一个代码逻辑,是会有多个线程来调用的,但是我们只能允许一个线程通过,别的线程只要发现有其他线程已经执行过这个方法那么就终止这个执行。

关键点

所以实现这种模式的关键点在于 如何知道别的线程已经执行过了,呃,那不就是那个变量留下痕迹不就行了, 所以需要一个共享变量来记录痕迹, 那么好了既然设计到共享变量那么就会有线程安全的问题,所以需要进行加,或者cas

示例,假设我们有一个服务,启动之后都会进行初始化

使用锁

/**
 * 服务器
 * @Author: puhaiguo
 * @Date: 2022-07-10 19:36
 * @Version 1.0
 */
public class Server {
    private boolean flag = false;
    
    public synchronized void start(){
        if (flag){
            return;
        }
        flag = true;
        init();
    }

    private void init() {
        System.out.println("进行初始化");
    }
}

public class Test {
    public static void main(String[] args) {
        Server server = new Server();

        for (int i = 0; i < 10; i++) {
            new Thread(server::start).start();
        }
    }
}

cas

/**
 * 服务器
 * @Author: puhaiguo
 * @Date: 2022-07-10 19:36
 * @Version 1.0
 */
public class Server {
    private volatile Boolean flag = false;
    
    public  void start(){
        if (flag){
            return;
        }
        /*开始进行cas尝试修改*/
        Unsafe unsafe = MyJUCUtil.getUnsafe();
        if (unsafe.compareAndSwapObject(this, getFlagAddr(), false, true)){
            init();
        }
    }

    private void init() {
        System.out.println("进行初始化");
    }
    
    private long getFlagAddr(){
        long addr = 0;
        try {
            Field flag = getClass().getDeclaredField("flag");
            Unsafe unsafe = MyJUCUtil.getUnsafe();
            addr = unsafe.objectFieldOffset(flag);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return addr;
    }
    
}

总结

终止模式 大概就是通过一个标记位,来控制线程执行逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值