Java并发 aqs

AQS:AbstractQueuedSynchronizer

一、AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器。

二、原理:AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。

原理图:

 

三、学习路线图。大量的应用在j.u.c下的各个基础类和工具栏,构成Java并发包的基础。

 四、1、有一个重要的状态标志——state,该属性是一个int值,表示对象的当前状态。三个protected final的方法来改变state的值,分别是:getState、setState(int)、compareAndSetState(int, int)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private volatile int state;
 
   /**
    * Returns the current value of synchronization state.
    * This operation has memory semantics of a {@code volatile} read.
    * @return current state value
    */
   protected final int getState() {
       return state;
   }
 
   /**
    * Sets the value of synchronization state.
    * This operation has memory semantics of a {@code volatile} write.
    * @param newState the new state value
    */
   protected final void setState(int newState) {
       state = newState;
   }

  

   2、AQS定义两种资源共享方式

  • Exclusive(独占):只有一个线程能执行,如ReentrantLock。又可分为公平锁和非公平锁:

    • 公平锁:按照线程在队列中的排队顺序,先到者先拿到锁
    • 非公平锁:当线程要获取锁时,无视队列顺序直接去抢锁,谁抢到就是谁的
  • Share(共享):多个线程可同时执行,如Semaphore/CountDownLatch。Semaphore、CountDownLatCh、 CyclicBarrier、ReadWriteLock 。

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// exclusive mode
protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }
 protected boolean tryRelease(int arg) {
        throw new UnsupportedOperationException();
    }
 
 
// shared mode共享模式
protected int tryAcquireShared(int arg) {
        throw new UnsupportedOperationException();
    }
 protected boolean tryReleaseShared(int arg) {
        throw new UnsupportedOperationException();
    }

3、用到了模板设计模式

五、同步工具类

CountDownLatch

倒数计时。是一个同步工具类,用来协调多个线程之间的同步。这个工具通常用来控制线程等待,它可以让某一个线程等待直到倒计时结束,再开始执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class CountDownLatchDemo implements Runnable {
 
    static final CountDownLatch latch = new CountDownLatch(10);
    static final CountDownLatchDemo demo = new CountDownLatchDemo();
 
    @Override
    public void run() {
        // 模拟检查任务
        try {
            Thread.sleep(new Random().nextInt(20) * 100);
            System.out.println("check complete");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 计数减一
            // 放在finally避免任务执行过程出现异常,导致countDown()不能被执行
            latch.countDown();
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        ExecutorService exec = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10; i++) {
            exec.submit(demo);
        }
 
        // 等待检查
        latch.await();
 
        // 发射火箭
        System.out.println("Fire!");
        // 关闭线程池
        exec.shutdown();
    }
 
}

Semaphore 

synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。

 

不错的博文:https://blog.csdn.net/lxltmac/article/details/84871929

https://segmentfault.com/a/1190000016885682

posted @   阿罗luo  阅读(189)  评论(0编辑  收藏  举报
编辑推荐:
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
阅读排行:
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
点击右上角即可分享
微信分享提示