• 【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
  • 相关阅读:
    com.google.code:kaptcha-2.3.jar
    正则表达式很难?记住这25个常用的就可以了!
    嵌入式软件的低功耗设计
    Linux进程间通信(二)
    斐波那契数列的递归优化《备忘录递归》
    一文看懂推荐系统:Gate网络2:百度GemNN(Gating-Enhanced Multi-Task Neural Networks)
    SpringBoot - WebMvcConfigurer的作用是什么?
    37~python 字符串
    K8S集群中Coredns域名解析故障排查思路
    彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)
  • 原文地址:https://blog.csdn.net/qq_45722630/article/details/134541358