intellij idea使用教程 底层架构 qt jScrollPane jquery触发点击事件 js的点击事件 java常用的包 coreldraw入门学习 centos查看python版本 java取绝对值 idea批量替换快捷键 python环境 eclipse安装python java数据库连接 java的substring java基础教学 java学习平台 java自定义异常 java删除文件 java的框架 java创建文件夹 php实例代码 离散数学及其应用 嵌入式linux驱动程序设计从入门到精通 shutil rar去广告 只狼脚本 mac画图工具 c4d挤压 linux解压 英雄联盟美图 cad合并成块 俄罗斯方块java php递归算法 qq网盘在哪里 postgresql中文手册 橙子助手 游戏录屏软件 ps怎么做表格 dnf霓裳仙子属性
当前位置: 首页 > 学习教程  > 编程语言

并发编程-AQS应用类实现原理

2021/1/29 0:05:20 文章标签:

并发编程-AQS应用类实现原理CountDownLatch重要函数CyclicBarrier应用场景CyclicBarrier 和 CountDownLatch的区别SemaphoreCountDownLatch CountDownLatch 允许一个或者多个线程等待其他线程完成操作。 重要函数 countDown() public void countDown() { //会调用 tryRelease…

并发编程-AQS应用类实现原理

  • CountDownLatch
    • 重要函数
  • CyclicBarrier
    • 应用场景
    • CyclicBarrier 和 CountDownLatch的区别
  • Semaphore

CountDownLatch

CountDownLatch 允许一个或者多个线程等待其他线程完成操作。

重要函数

countDown()

public void countDown() {
//会调用 tryReleaseShared()
       sync.releaseShared(1);
   }
   
public final boolean releaseShared(int arg) {
//如果没有锁了 去唤醒
    if (tryReleaseShared(arg)) {
    //唤醒线程 如果state=0 这里面会重复去唤醒下一个节点。这样会全部被唤醒
        doReleaseShared();
        return true;
    }
    return false;
}

protected boolean tryReleaseShared(int releases) {
   for (;;) {
   //获取State
       int c = getState();
      // 如果原本等于0 直接退出,因为其他线程已经开始唤醒开始唤醒。
       if (c == 0)
           return false;
        
       int nextc = c-1;
       //利用自旋将state-1;如果 为零,可以开始唤醒
       if (compareAndSetState(c, nextc))
           return nextc == 0;
   }
}

await()

//将这个线程放入同步等待队列 由于state= count 所以会阻塞。
public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

CyclicBarrier

应用场景

CyclicBarrier 可以用于多线程计算数据,最后合并结果的场景。

代码应用

public class CyclicBarrierRunner implements Runnable {
    private CyclicBarrier cyclicBarrier;
    private int index ;

    public CyclicBarrierRunner(CyclicBarrier cyclicBarrier, int index) {
        this.cyclicBarrier = cyclicBarrier;
        this.index = index;
    }

    public void run() {
        try {
            System.out.println("index: " + index);
            cyclicBarrier.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(11, new Runnable() {
            public void run() {
                System.out.println("所有特工到达屏障,准备开始执行秘密任务");
            }
        });
        for (int i = 0; i < 10; i++) {
            new Thread(new CyclicBarrierRunner(cyclicBarrier, i)).start();
        }
        //这里阻塞,直到其他线程都跑完,也就是跑完10 个await
        cyclicBarrier.await();
        System.out.println("全部到达屏障....1");

    }

}

CyclicBarrier 和 CountDownLatch的区别

  • CountDownLatch 计数器只能使用一次,而CyclicBarrier可以用reset()重新设置。
  • CyclicBarrier还提供其他有用的方法,比如getNumberWaiting()可以获取阻塞线程数量。isBroken()方法用来了解阻塞的线程是否被打断。

Semaphore

Semaphore 是用来控制同时访问特定资源的线程数量。通过调节各个线程,以保证合理的使用公共资源。

public class SemaphoreRunner {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2);
        for (int i=0;i<5;i++){
            new Thread(new Task(semaphore,"yangguo+"+i)).start();
            //CountDownLatch
        }
    }

    static class Task extends Thread{
        Semaphore semaphore;



        public Task(Semaphore semaphore,String tname){
            this.semaphore = semaphore;
            this.setName(tname);
        }

        public void run() {
            try {
                semaphore.acquire();
                System.out.println(Thread.currentThread().getName()+":aquire() at time:"+System.currentTimeMillis());
                Thread.sleep(1000);
                semaphore.release();
//                System.out.println(Thread.currentThread().getName()+":aquire() at time:"+System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

本文链接: http://www.dtmao.cc/news_show_650361.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?