• 【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
  • 相关阅读:
    国庆作业 day 10.1
    Python博客系统源代码,基于Django + Vue.js +MySql,毕业设计
    学习java第五十一天
    基于java+springmvc+mybatis+vue+mysql的婚纱影楼
    [二进制学习笔记]Ubuntu20.04关闭开启ASLR
    「PAT甲级真题解析」Advanced Level 1006 Sign In and Sign Out
    顺序表第一部分(介绍篇),三部曲后面分别是实现和介绍
    openssl开发详解
    21天打卡挑战学习MySQL——《MySQL表管理》第二周 第五篇
    PostgreSQL-基本结构
  • 原文地址:https://blog.csdn.net/qq_45722630/article/details/134541358