JUC包下的几个辅助类

1、semaphore

Semaphore中文解释成信号量的意思,可以看成一个可获数量有限的共享锁。锁只可被有限数量线程使用。

这个辅助类的核心方法是acquire以及release方法。acquire方法用于获取许可,release用于归还一个许可。

acquire方法其默认调用的是非公平的获取方法。意思也就是每当执行一次这个acquire方法,便会将你指定的avaliable(你指定的数量的许可证)减1。并将剩余的许可证数量利用CAS算法设置为还可获取到的avaliable数量。随后返回这个剩余数量。这里用到了一个无限for循环用于保证线程安全。这个获取许可证的操作是没有“上锁”的。故而利用这个无限循环+CAS的形式便可以确保当多个线程获取许可的时候,造成的avaliable不一致的情况。

final int nonfairTryAcquireShared(int acquires) {
    for (;;) {
        int available = getState();
        int remaining = available - acquires;
        if (remaining < 0 ||
            compareAndSetState(available, remaining))
            return remaining;
    }
}
非公平锁也就是说线程获取锁的顺序是不一定的。而公平锁是按照先来后到的顺序获取锁。
acquire方法是一个阻塞式的,其内部使用类无限循环以及locksupport去持续获取许可,当获取不到时会调用park方法阻塞线程。
还有tryAcquire方法,这个方法的意思跟trylock类型,意思就是获取不到就返回false去做别的事情。
release方法:释放许可。
注意在调用release方法之前不一定要调用acquire方法。

使用场景:我们一般使用信号量来限制访问资源的线程数量,比如说篮球场五个最多被使用。则如下:
for(int x = 0;x<12;x++) {
  new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                semaphore.acquire();
                System.out.println("班级" + Thread.currentThread() + "正在篮球场 踢球");
                Thread.sleep(3000);
                System.out.println("班级" + Thread.currentThread() +" 结束踢球");
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();
}
那这个信号量Semaphore和Reentranlock的区别。
首先这个lock方法一定要先于unlock方法执行。如若不然会运行时异常 java.lang.IllegalMonitorStateException。但是Semaphore可以允许非owner线程执行其他线程的锁操作。
随后Semaphore可以通过非owner的线程来实现死锁恢复,但Lock则做不到。要使用Lock.unlock()来释放锁,首先你得拥有这个锁对象,因此非owner线程(事先没有拥有锁)是无法去释放别的线程的锁对象


Exchanger:这个辅助类可以看成是双向数据传输的SynchronousQueue。即没有消费者生产者之分,任意两个线程可以交换数据。
核心方法是:exchange.


CyclicBarrier:只允许一组线程彼此等待,直到所有线程到达指定集合点。
CountDownLatch:导游线程等待其他线程到达。
这两个的区别在于:(摘自博主https://www.cnblogs.com/kexianting/p/8566318.html)
CountDownLatchCyclicBarrier
减计数方式加计数方式
计算为0时释放所有等待的线程计数达到指定值时释放所有等待线程
计数为0时,无法重置计数达到指定值时,计数置为0重新开始
调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞

不可重复利用

 


那具体到底这两个是如何使用的呢?

CountDownLatch可以看作是一个倒计时装置。

例如:主线程就是一个司机,那其他待执行的线程就相当于乘客。CountDownLatch的数量就相当于是车上的座位。乘客一个个上车直到全部坐满。

static CountDownLatch countDownLatch = new CountDownLatch(20);
static class Passenger extends Thread {
     @Override
     public void run() {
         synchronized (CountDownLatch.class) {
             System.out.println("乘客" + Thread.currentThread() + "上车");
             countDownLatch.countDown();
             System.out.println("车上还剩"+countDownLatch.getCount());
         }
     }
 }
 public static void main(String[] args){
     for(int x = 0;x<23;x++){
         new Passenger().start();
     }
     try {
         countDownLatch.await();
         System.out.println("客车已满,司机发车!!");
     } catch (InterruptedException e) {
         e.printStackTrace();
     }
 }
 

而CyclicBarrier可以看成是一个障碍,只有所有的人齐心协力才可以共同越过这个障碍。

可重复利用
 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的JUCjava.util.concurrent)包提供了一些并发编程中常用的,这些可以帮助我们更方便地实现多线程编程。以下是一些常用的JUC及其解析: 1. CountDownLatch(倒计时器) CountDownLatch是一个计数器,它允许一个或多个线程等待一组事件发生后再继续执行。它最基本的方法是await()和countDown()。await()方法会阻塞当前线程,直到计数器的值为0;countDown()方法会将计数器的值减1。 2. CyclicBarrier(循环屏障) CyclicBarrier是一个同步工具,它允许一组线程等待彼此达到一个公共屏障点。当所有线程都到达这个屏障点时,它们才能继续执行。CyclicBarrier可以被重复使用,当所有线程都执行完后,它会自动重置。 3. Semaphore(信号量) Semaphore是一种计数器,它维护了一组许可证。当调用acquire()方法时,线程会阻塞,直到许可证可用;而当调用release()方法时,许可证的数量会增加。Semaphore可以用于限制同时访问某些资源的线程数量。 4. ReentrantLock(重入锁) ReentrantLock是一个可重入的互斥锁。它和synchronized关键字似,但是提供了更多的灵活性和功能。ReentrantLock中最常用的方法是lock()和unlock(),它们分别用于获取锁和释放锁。 5. ConcurrentHashMap(并发哈希表) ConcurrentHashMap是一个线程安全的哈希表实现。它和HashMap似,但是支持并发访问。ConcurrentHashMap中的所有方法都是线程安全的,而且它的性能比Hashtable和同步的HashMap要好。 6. Executors(线程池) Executors是一个工厂,用于创建各种型的线程池。它提供了一些静态方法,例如newFixedThreadPool()、newCachedThreadPool()、newSingleThreadExecutor()等,可以方便地创建各种型的线程池。 7. Future(异步计算) Future是一个接口,它表示一个异步计算的结果。Future可以通过get()方法获取计算结果,或者通过cancel()方法取消计算。Future还可以用于实现一些高级的并发操作,例如等待一组异步计算全部完成后再继续执行。 总的来说,JUC包提供了很多有用的和工具,可以帮助我们更方便地实现多线程编程,提高程序的并发性能和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值