java并发编程(六)----(JUC)Semaphore

Semaphore,从字面意义上我们知道他是信号量的意思。在java中,一个计数信号量维护了一个许可集。Semaphore 只对可用许可的号码进行计数,并采取相应的行动。拿到信号量的线程可以进入代码,否则就等待。通过acquire()和release()获取和释放访问许可。

信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个“共享锁”。

Java并发提供了两种加锁模式:共享锁和独占锁。前面介绍的ReentrantLock就是独占锁。对于独占锁而言,它每次只能有一个线程持有,而共享锁则不同,它允许多个线程并行持有锁,并发访问共享资源。

独占锁它所采用的是一种悲观的加锁策略, 对于写而言为了避免冲突独占是必须的,但是对于读就没有必要了,因为它不会影响数据的一致性。如果某个只读线程获取独占锁,则其他读线程都只能等待了,这种情况下就限制了不必要的并发性,降低了吞吐量。而共享锁则不同,它放宽了加锁的条件,采用了乐观锁机制,它是允许多个读线程同时访问同一个共享资源的。

举一个生活中的例子,有一条单行道路口有一红绿灯在正常的绿灯时间内如果骑车速度都很平均只能过去20辆车,这就意味着排在前面的20辆肯定能过去红绿灯,后面的就只能等下一个绿灯了。但是如果这个时候有车不想过去这个路口它驶向了边上别的路,那么后面的车就有机会。下面我们来看一个简单的例子:

public class TestSemaphore {
    public static void main(String[] args) {
        final Semaphore semaphore = new Semaphore(5);
        ExecutorService executorService = Executors.newCachedThreadPool();
        for(int i = 0;i<10;i++){
            int j = 0;
            executorService.submit(new A("car"+(j++),semaphore),"Thread"+(j++));
            //new Thread(new A("car"+(j++),semaphore),"Thread"+(j++)).start();
            if(i == 5){
                try {
                    Thread.sleep(1000);
                    System.out.println("最后还有"+semaphore.availablePermits()+"个许可可用");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        System.out.println("最后还有"+semaphore.availablePermits()+"个许可可用");
    }

    }
    class A implements Runnable{
        String carName;
        private Semaphore semaphore;

        public A(String carName, Semaphore semaphore){
            this.carName = carName;
            this.semaphore = semaphore;
        }

        public void getWay(){
            System.out.println("this car is get the way" + Thread.currentThread().getName());
        }

        public void run() {
            try {
                if(semaphore.availablePermits() > 0){
                    semaphore.acquire();
                    getWay();
                    semaphore.release();
                }else{
                    System.out.println("请等待========");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值