Java并发编程之JUC辅助类Semaphore------信号量 一个例子看懂

一.场景引入


现在有6个车,要抢占三个车位,占用车位几秒后,离开车位


二.代码示例

public static void main(String[] args) {

        Semaphore semaphore = new Semaphore(3);

        for (int i = 1; i <= 6 ; i++) {

            new Thread(()->{

                try {
                    semaphore.acquire();

                    System.out.println(Thread.currentThread().getName()+"\t抢占到了车位");

                    //暂停一会线程
                    TimeUnit.SECONDS.sleep(3);

                    System.out.println(Thread.currentThread().getName()+"\t离开了车位");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }

            },String.valueOf(i)).start();
        }
    }

运行结果:

"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe" "-javaagent:D:\idea\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar=56223:D:\idea\IntelliJ IDEA 2019.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\李肇京\IdeaProjects\JUC\out\production\JUC" JUC_01_SellTicket.HelperClasses.SemaphoreDemo
1	抢占到了车位
2	抢占到了车位
3	抢占到了车位
1	离开了车位
4	抢占到了车位
2	离开了车位
5	抢占到了车位
3	离开了车位
6	抢占到了车位
4	离开了车位
5	离开了车位
6	离开了车位

Process finished with exit code 0

三.Semaphore介绍

  • JDK官方:一个计数信号量。 在概念上,信号量维持一组许可
  • 在信号量上我们定义两种操作:
    • acquire(获取) 当一个线程调用acquire操作时,它要么通过成功获取信号量(信号量减1),要么一直等下去,直到有线程释放信号量,或超时
    • release(释放)实际上会将信号量的值加1,然后唤醒等待的线程。

这里我们通过信号量的构造方法传入一个限制参数为3,说明最多有三个线程占用资源,acquire有两种结果,一种是拿到信号量,信号量减一;要么没拿到,则阻塞。此处我们有三个车没有拿到,为阻塞状态,但是当占用车位的线程调用release后,之前没进过车位的也有机会进入了。而且已经进过车位的线程因为已经运行结束了,所以无法再次抢占资源



  • 信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章