JUC CyclicBarrier和Semphore

简介: JUC CyclicBarrier和Semphore

CyclicBarrier

允许一组线程全部等待彼此达到共同屏障点的同步辅助

      CyclicBarrier也是一个计数器,只不过它是  加数器 CountDownLatch是减数器

代码测试:集齐7个龙珠召唤神龙

package com.wyh.JUCUtil;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
 * @program: JUC
 * @description:
 * @author: 魏一鹤
 * @createDate: 2022-02-18 22:28
 **/
//CyclicBarrier屏蔽 本质就是一个增数器
//集齐七颗龙珠召唤神龙
public class CyclicBarrierDemo   {
public static void main(String[] args){
//创建CyclicBarrier
        //需要两个参数  它有两个参数 1 计数大小 2 runnable线程 这里直接用lambda表达式
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
            //计数器到7才会召唤神龙
            System.out.println("召唤神龙成功");
        });
//创建7个线程
        for (int i = 1; i <= 7; i++) {
   //lambda表达式能操作到循环变量i吗 答案是不能的
            //想要再lambda表达式使用循环变量i 需要定义final常量 然后再lambda表达式使用常量
            final int temp=i;
new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "收集了"+temp+"颗龙珠");   
                try {
//等待计数器执行完了 也就是变成7 需要抛异常
 cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}


Thread-0收集了1颗龙珠

Thread-4收集了5颗龙珠

Thread-5收集了6颗龙珠

Thread-3收集了4颗龙珠

Thread-2收集了3颗龙珠

Thread-1收集了2颗龙珠

Thread-6收集了7颗龙珠

召唤神龙成功



结果和我们想要的是一样的 但是如果我们把计数值换成8,但是只能集齐7会怎么样 程序会卡死在这,因为它永远也不能计数成8,await()方法只能等的就是计数完成之后执行,由于计数一直完不成就会一直等待


package com.wyh.JUCUtil;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
 * @program: JUC
 * @description:
 * @author: 魏一鹤
 * @createDate: 2022-02-18 22:28
 **/
//CyclicBarrier屏蔽 本质就是一个增数器
//集齐七颗龙珠召唤神龙
public class CyclicBarrierDemo   {
public static void main(String[] args){
//创建CyclicBarrier
        //需要两个参数  它有两个参数 1 计数大小 2 runnable线程 这里直接用lambda表达式
        CyclicBarrier cyclicBarrier = new CyclicBarrier(8,()->{
            //计数器到7才会召唤神龙
            System.out.println("召唤神龙成功");
        });
 //创建7个线程
        for (int i = 1; i <= 7; i++) {
//lambda表达式能操作到循环变量i吗 答案是不能的
            //想要再lambda表达式使用循环变量i 需要定义final常量 然后再lambda表达式使用常量
            final int temp=i;
new Thread(()->{
                System.out.println(Thread.currentThread().getName() + "收集了"+temp+"颗龙珠");
//等待计数器执行完了 也就是变成7 需要抛异常
                try {
                     cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}


Thread-1收集了2颗龙珠

Thread-4收集了5颗龙珠

Thread-2收集了3颗龙珠

Thread-3收集了4颗龙珠

Thread-0收集了1颗龙珠

Thread-6收集了7颗龙珠

Thread-5收集了6颗龙珠


Semphore

Semphore:信号量  主要用作限流


//创建Semaphore  需要一个参数线程数量参数  停车位 3个

Semaphore semaphore = new Semaphore(3);

//得到

semaphore.acquire();

//释放

semaphore.release();


代码实现 抢车位 6个车 3个车位  123号车进去停车位456号车等待 1号车出去4好车进来


package com.wyh.JUCUtil;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
 * @program: JUC
 * @description: Semaphore停车位测试
 * @author: 魏一鹤
 * @createDate: 2022-02-18 23:12
 **/
//Semaphore限流
public class SemaphoreDemo {
public static void main(String[] args) {
        //创建Semaphore  需要一个参数线程数量参数  停车位 3个
        //它主要有两个方法 acquire()得到 release()释放
        Semaphore semaphore = new Semaphore(3);
//创建6个线程 6个车
        for (int i = 1; i <= 6; i++) {
new Thread(()->{
                try {
 //得到  需要抛异常
                    semaphore.acquire();
//抢到车位
                    System.out.println(Thread.currentThread().getName() + "抢到了车位");
      //休眠两秒
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(Thread.currentThread().getName() + "离开了车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
 //释放
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}


1抢到了车位

3抢到了车位

2抢到了车位

1离开了车位

3离开了车位

2离开了车位

5抢到了车位

4抢到了车位

6抢到了车位

5离开了车位

6离开了车位

4离开了车位


原理

主要是Semaphore 的两个方法

acquire()得到   假设如果已经满了,等待被释放为止

release()释放   释放,会将当前的释放量+1,然后唤醒等待线程

作用

1 多个共享资源互斥的使用

2 并发限流  控制最大的线程数 保证服务器的安全和高可用

目录
相关文章
|
4月前
|
Java
JUC 常用 4 大并发工具类 CountDownLatch、CyclicBarrier、Semaphore、ExChanger
JUC 常用 4 大并发工具类 CountDownLatch、CyclicBarrier、Semaphore、ExChanger
|
JavaScript 小程序 Java
JUC多线程:CountDownLatch、CyclicBarrier、Semaphore 同步器原理 上
JUC多线程:CountDownLatch、CyclicBarrier、Semaphore 同步器原理 上
|
消息中间件 JavaScript 小程序
JUC多线程:CountDownLatch、CyclicBarrier、Semaphore 同步器原理 下
JUC多线程:CountDownLatch、CyclicBarrier、Semaphore 同步器原理 下
JUC并发编程——CountDownLatch&Semaphore&CyclicBarrier
JUC并发编程——CountDownLatch&Semaphore&CyclicBarrier
122 0
JUC并发编程——CountDownLatch&Semaphore&CyclicBarrier
|
安全 Dubbo Java
JUC系列(七)| JUC三大常用工具类CountDownLatch、CyclicBarrier、Semaphore
JUC系列(七)| JUC三大常用工具类CountDownLatch、CyclicBarrier、Semaphore
417 0
JUC系列(七)| JUC三大常用工具类CountDownLatch、CyclicBarrier、Semaphore
|
算法 Java 数据库
Java并发:同步工具类详解(CountDownLatch、CyclicBarrier、Semaphore)
Java并发:同步工具类详解(CountDownLatch、CyclicBarrier、Semaphore)
259 0
【小家java】JUC并发编程工具之CountDownLatch(闭锁)、CyclicBarrier、Semaphore的使用(中)
【小家java】JUC并发编程工具之CountDownLatch(闭锁)、CyclicBarrier、Semaphore的使用(中)
【小家java】JUC并发编程工具之CountDownLatch(闭锁)、CyclicBarrier、Semaphore的使用(下)
【小家java】JUC并发编程工具之CountDownLatch(闭锁)、CyclicBarrier、Semaphore的使用(下)
|
NoSQL Java Redis
【小家java】JUC并发编程工具之CountDownLatch(闭锁)、CyclicBarrier、Semaphore的使用(上)
【小家java】JUC并发编程工具之CountDownLatch(闭锁)、CyclicBarrier、Semaphore的使用(上)
【小家java】JUC并发编程工具之CountDownLatch(闭锁)、CyclicBarrier、Semaphore的使用(上)