AQS

模板方法模式:

模板:

package com.atguigu.springcloud.template;

/**
 * 抽象模板类Cook
 * 步骤一:cookOne
 * 步骤二:cookTwo
 * 步骤三:cookThree
 * 提供一个标准模板,执行顺序分别为一,二,三
 */
public abstract class Cook {

    //抽象类的抽象方法没有方法体,类似于接口方法
    public abstract void cookOne();

    public abstract void cookTwo();

    public abstract void cookThree();

    /**
     * 钩子函数
     * 让子类决定cookTwo方法在模板中是否执行
     */
    public boolean isTwo() {
        return true;
    }

    /**
     * 执行cook操作分别需要执行模板方法一,二,三
     * 具体的三个方法由子类具体实现
     * final修饰方法,此处则不允许重写
     */
    final public void cook() {
        cookOne();
        if (isTwo()) {
            cookTwo();
        }
        cookThree();
    }
}

子类一:

package com.atguigu.springcloud.template.implement;

import com.atguigu.springcloud.template.Cook;

public class SmallCook extends Cook {

    //此处定义false,则cook方法中不执行cookTwo()
    private boolean isTwo = false;

    @Override
    public boolean isTwo() {
        return isTwo;
    }

    @Override
    public void cookOne() {
        System.out.println("small执行步骤一");
    }

    @Override
    public void cookTwo() {
        System.out.println("small执行步骤二");
    }

    @Override
    public void cookThree() {
        System.out.println("small执行步骤三");
    }
}

 

子类二:

package com.atguigu.springcloud.template.implement;

import com.atguigu.springcloud.template.Cook;

public class BigCook extends Cook {

    //此处定义false,则cook方法中不执行cookTwo()
    private boolean isTwo = true;

    @Override
    public boolean isTwo() {
        return isTwo;
    }

    @Override
    public void cookOne() {
        System.out.println("Big执行步骤一");
    }

    @Override
    public void cookTwo() {
        System.out.println("Big执行步骤二");
    }

    @Override
    public void cookThree() {
        System.out.println("Big执行步骤三");
    }
}

 

Test:

package com.atguigu;

import com.atguigu.springcloud.template.implement.BigCook;
import com.atguigu.springcloud.template.implement.SmallCook;
import org.junit.Test;

public class TemplateTest {

    @Test
    public void test() {
        SmallCook smallCook = new SmallCook();
        smallCook.cook();
        BigCook bigCook = new BigCook();
        bigCook.cook();
    }
}

 

结果:

small执行步骤一
small执行步骤三
Big执行步骤一
Big执行步骤二
Big执行步骤三

AQS底层使用了模板方法模式:只需要继承AbstractQueuedSynchronizer类,并重写一部分方法

package com.atguigu.springcloud.util;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * 基于AQS自定义锁,实现互斥锁
 * 典型的模板方法模式:
 * 直接继承AbstractQueuedSynchronizer父类,子类实现具体的方法实现
 */
public class Sync extends AbstractQueuedSynchronizer {

    /**
     * tryAcquire方法是用来尝试获取独占资源
     * compareAndSetState方法:state为0才设置为1,不可重入
     * setExclusiveOwnerThread设置当前线程独占资源
     */
    @Override
    protected boolean tryAcquire(int arg) {
        if (compareAndSetState(0, 1)) {
            setExclusiveOwnerThread(Thread.currentThread());//互斥锁,共享锁
            return true;
        }
        return false;
    }

    /**
     * tryRelease方法是用来尝试释放资源
     * 所以将state设置为0
     */
    @Override
    protected boolean tryRelease(int arg) {
        setExclusiveOwnerThread(null);
        setState(0);
        return true;
    }

    /**
     * 判断该线程是否独占资源
     */
    @Override
    protected boolean isHeldExclusively() {
        return getState() == 1;
    }
}

 

CLH队列(三位作者名称缩写):

CLH队列是FIFO(First Input First Output,先进先出)的双端双向队列,实现公平锁。线程通过AQS获取锁失败,就会将线程封装成一个Node节点,插入队列尾。当有线程释放锁时,后尝试把队头的next节点占用锁

AbstractQueuedSynchronizer类定义了名为Node的内部类,并在AbstractQueuedSynchronizer中已经实现了对线程队列的维护,所以自定义同步器只需要实现isHeldExclusively()等方法即可(上面的demo):

static final class Node {
    static final Node SHARED = new Node();
    static final Node EXCLUSIVE = null;
    static final int CANCELLED =  1;
    static final int SIGNAL    = -1;
    static final int CONDITION = -2;
    static final int PROPAGATE = -3;

    volatile int waitStatus;

    volatile Node prev;

    volatile Node next;

    volatile Thread thread;

    Node nextWaiter;

    final boolean isShared() {
        return nextWaiter == SHARED;
    }

    final Node predecessor() throws NullPointerException {
        Node p = prev;
        if (p == null)
            throw new NullPointerException();
        else
            return p;
    }

    Node() {    
    }

    Node(Thread thread, Node mode) {
        this.nextWaiter = mode;
        this.thread = thread;
    }

    Node(Thread thread, int waitStatus) {
        this.waitStatus = waitStatus;
        this.thread = thread;
    }
}

AbstractQueuedSynchronizer类中的具体方法不再描述:

部分转自:

https://www.cnblogs.com/waterystone/p/4920797.html

https://blog.csdn.net/mulinsen77/article/details/84583716

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值