• 【Java并发编程十】同步控制二


    Semaphore 信号量

     Semaphore可以减少负载,使限制同时运行的线程数量。Semaphore的执行过程是先获取一定数量的线程,执行完一个释放一个semaphore,再去执行一个新的线程。

    import java.util.ArrayList;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    public class myTest implements Runnable{
        // semaphore表示信号量
        final Semaphore semaphore = new Semaphore(5);
        public static void main(String[] args) {
            // 线程池
            ExecutorService executorService = Executors.newFixedThreadPool(20);
            final myTest test = new myTest();
            for(int i=0; i<20; i++) {
                executorService.submit(test);
            }
        }
        @Override
        public void run() {
            try {
                long startTime = System.currentTimeMillis();
                // semaphore数量超过限制的数量,自身便会阻塞
                semaphore.acquire();
                Thread.sleep(2000);
                semaphore.release();
                long endTime = System.currentTimeMillis();
                System.out.println(Thread.currentThread().getId()+" cost " + (endTime-startTime) + " ms");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    /**
    由于设置semaphore最大数量为5,所以同一时刻最多有五个线程同时运行。
    25 cost 2010 ms
    27 cost 2010 ms
    26 cost 2010 ms
    24 cost 2010 ms
    28 cost 2010 ms
    33 cost 4010 ms
    30 cost 4010 ms
    29 cost 4019 ms
    31 cost 4018 ms
    32 cost 4018 ms
    38 cost 6012 ms
    35 cost 6012 ms
    37 cost 6019 ms
    43 cost 6019 ms
    36 cost 6028 ms
    */
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    CountDownLatch 倒计时器

     CountDowmLatch是每次等到一定数量,end.await() 才会放行。

    package myTest;
    
    import java.util.ArrayList;
    import java.util.Random;
    import java.util.concurrent.*;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class myTest implements Runnable{
        static final CountDownLatch end = new CountDownLatch(10);
        static final myTest test = new myTest();
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for(int i=0; i<20; i++) {
                executorService.submit(test);
            }
            // 等待所有线程就绪
            end.await();
            System.out.println("开始");
            executorService.shutdown();
        }
    
        @Override
        public void run() {
            try {
                long startTime = System.currentTimeMillis();
                Thread.sleep(new Random().nextInt(10)*100);
                long endTime = System.currentTimeMillis();
                System.out.println("共执行 "+ (endTime-startTime) + " ms");
                end.countDown();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
    
        }
    }
    
    • 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
    • 37

    CyclicBarrier 循环栅栏

     CyclicBarrier可以重复被利用,而CountDownLatch不行。
     CyclicBarrier正如它的名字一样,循环栅栏,栅栏是一个阻挡别人进入的障碍物,CyclicBarrier和CountDownLatch一样有一个计数器,不过CountDownLatch的计数器被定义了之后就只能被一直减少,最后减少到0时,完全结束,而CyclicBarrier的计数器则是从0开始增加,直到指定数值时开始放行,然后计数器归零,并等待下一波线程的访问

    import java.util.ArrayList;
    import java.util.Random;
    import java.util.concurrent.*;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class myTest implements Runnable{
        static final CyclicBarrier end = new CyclicBarrier(5);
        static final myTest test = new myTest();
    
        public static void main(String[] args) throws InterruptedException {
            ExecutorService executorService = Executors.newFixedThreadPool(20);
            for(int i=0; i<20; i++) {
                executorService.submit(test);
            }
    
            executorService.shutdown();
        }
    
        @Override
        public void run() {
            try {
                long startTime = System.currentTimeMillis();
                Thread.sleep(new Random().nextInt(10)*100);
                end.await();
                System.out.println(Thread.currentThread().getId()+"集合完成");
                end.await();
                long endTime = System.currentTimeMillis();
                System.out.println(Thread.currentThread().getId() + " 执行完毕: "+ endTime + " ms");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (BrokenBarrierException e) {
                throw new RuntimeException(e);
            }
    
        }
    }
    
    
    • 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
    • 37
    • 38
  • 相关阅读:
    Flink监控和调优笔记
    LeetCode54.螺旋矩阵
    一点感受
    基于多级适应方法的无人机(UAV)在发动机输出情况下的导航和路径规划附Matlab代码
    336_C++_ImageBuffer类管理ImagesCache类,ImagesCache负责在进程地址空间中映射给定大小区域,处理较大数据的缓存和缓冲
    【Python & Other】一网打尽 Python复制文本&文件到剪切板
    阿里云服务器(Ubuntu22)上的MySQL8更改为大小写不敏感
    Bobo Python 学习笔记
    部署LVS-NAT群集实验
    SpringBoot 04 多环境配置和配置文件小技巧
  • 原文地址:https://blog.csdn.net/qq_45722630/article/details/134541358