ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

同步类

2022-07-09 16:32:19  阅读:131  来源: 互联网

标签:同步 barrier Thread Semaphore System 线程 CountDownLatch


1.Semaphore (信号量)

Semaphore 是一种基于计数的信号量,用来控制同时访问的线程数。

它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做完自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。Semaphore 可以用来构建一些对象池,资源池之类的,比如数据库连接池

实现互斥锁(计数器为 1) 我们也可以创建计数为 1 的 Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量, 表示两种互斥状态。

 1 // 创建一个计数阈值为 5 的信号量对象
 2 // 只能 5 个线程同时访问
 3 Semaphore semp = new Semaphore(5);
 4 try { // 申请许可
 5 semp.acquire();
 6 try {
 7 // 业务逻辑
 8 } catch (Exception e) {
 9 } finally {
10 // 释放许可
11 semp.release();
12 }
13 } catch (InterruptedException e) {
14 }

Semaphore 中也有Sync内部类(继承AQS抽象类),semp.acquire()方法和semp.release()方法底层使用Sync类CAS修改其内部volatile共享变量state来获取许可。state可以设置大于1,也就是成为了共享锁。

Semaphore semp = new Semaphore(5);就是将state设置为5,每次一个线程获得信号量就-1,释放一个信号量就+1。

 

Semaphore 与 ReentrantLock比较

Semaphore 基本能完成 ReentrantLock 的所有工作,使用方法也与之类似,通过 acquire()与 release()方法来获得和释放临界资源。经实测,Semaphone.acquire()方法默认为可响应中断锁, 与 ReentrantLock.lockInterruptibly()作用效果一致,也就是说在等待临界资源的过程中可以被 Thread.interrupt()方法中断。 此外,Semaphore 也实现了可轮询的锁请求与定时锁的功能,除了方法名 tryAcquire 与 tryLock 不同,其使用方法与 ReentrantLock 几乎一致。Semaphore 也提供了公平与非公平锁的机制,也可在构造函数中进行设定。 Semaphore 的锁释放操作也由手动进行,因此与 ReentrantLock 一样,为避免线程因抛出异常而无法正常释放锁的情况发生,释放锁的操作也必须在 finally 代码块中完成。

 

 

CountDownLatch

CountDownLatch(线程计数器 )
 

作用:让一个线程等待其他几个线程执行特定操作(调用countDown方法)后才能继续执行

CountDownLatch 类位于 java.util.concurrent 包下,利用它可以实现类似计数器的功能。比如有 一个任务 A,它要等待其他 4 个任务执行完毕之后才能执行,此时就可以利用 CountDownLatch 来实现这种功能了。

CountDownLatch 调用await方法当前线程会被阻塞,等待latch调用countDown(),count为0(Sync中state为0),此线程就会被唤醒。

 

 1 final CountDownLatch latch = new CountDownLatch(2);
 2 new Thread(){public void run() {
 3 System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
 4  Thread.sleep(3000);
 5  System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
 6  //重点
 7  latch.countDown();
 8 };}.start();
 9 new Thread(){ public void run() {
10 System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
11  Thread.sleep(3000);
12  System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
13  latch.countDown();
14 };}.start();
15 System.out.println("等待 2 个子线程执行完毕...");
16 //重点
17 latch.await();  //主线程执行,等待两个子线程调用 latch.countDown();
18 System.out.println("2 个子线程已经执行完毕");
19 System.out.println("继续执行主线程");
20 }

 

CyclicBarrier

回环栅栏-等待至 barrier 状态再全部同时执行

字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态(一组线程都调用await)之后再全部同时后续执行

叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier 可以被重用。我们暂且把这个状态就叫做 barrier,当调用 await()方法之后,线程就处于 barrier 了。

CyclicBarrier 中最重要的方法就是 await 方法,它有 2 个重载版本: 1. public int await():用来挂起当前线程,直至所有线程都到达 barrier 状态再同时执行后续任务; 2. public int await(long timeout, TimeUnit unit):让这些线程等待至一定的时间,如果还有线程没有到达 barrier 状态就直接让到达 barrier 的线程执行后续任务。

具体使用如下,另外 CyclicBarrier 是可以重用的。

 

 1 public static void main(String[] args) {
 2  int N = 4;
 3     
 4  CyclicBarrier barrier = new CyclicBarrier(N);
 5     
 6  for(int i=0;i<N;i++)
 7      
 8  new Writer(barrier).start();
 9     
10  }
11  static class Writer extends Thread{
12    private CyclicBarrier cyclicBarrier;
13    public Writer(CyclicBarrier cyclicBarrier) {
14    this.cyclicBarrier = cyclicBarrier;
15    }
16   @Override
17   public void run() {
18     try {
19     Thread.sleep(5000); //以睡眠来模拟线程需要预定写入数据操作
20     System.out.println("线程"+Thread.currentThread().getName()+"写入数据完
21     毕,等待其他线程写入完毕");
22                    
23     cyclicBarrier.await();
24                    
25  } catch (InterruptedException e) {
26  e.printStackTrace();
27  }catch(BrokenBarrierException e){
28  e.printStackTrace();
29  }
30  System.out.println("所有线程写入完毕,继续处理其他任务,比如数据操作");
31  }
32  }

 

 

 

 

 

 

 

 

 

 

标签:同步,barrier,Thread,Semaphore,System,线程,CountDownLatch
来源: https://www.cnblogs.com/SEU-ZCY/p/16461188.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有