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  阅读(192)  评论(0编辑  收藏  举报
编辑推荐:
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
阅读排行:
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· 软件产品开发中常见的10个问题及处理方法
· Vite CVE-2025-30208 安全漏洞
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· MQ 如何保证数据一致性?
点击右上角即可分享
微信分享提示