java并发编程专题(六)----浅析(JUC)Semaphore

 更新时间:2020年07月01日 10:59:11   作者:rickiyang  
这篇文章主要介绍了java JUC)Semaphore的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下

半路开始看的朋友可以回顾一下前几篇

java并发编程专题(一)----线程基础知识

java并发编程专题(二)----如何创建并运行java线程

java并发编程专题(三)----详解线程的同步

java并发编程专题(四)----浅谈(JUC)Lock锁

java并发编程专题(五)----详解(JUC)ReentrantLock

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();
   }
  }
 }

以上就是java并发编程专题(六)----浅析(JUC)Semaphore的详细内容,更多关于JAVA Semaphore的资料请关注脚本之家其它相关文章!

相关文章

  • JDK  keytool证书工具功能代码解析

    JDK keytool证书工具功能代码解析

    这篇文章主要介绍了JDK keytool证书工具功能代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • 使用Spring Security控制会话的方法

    使用Spring Security控制会话的方法

    在本文中,我们将说明Spring Security如何允许我们控制HTTP会话。这篇文章主要介绍了使用Spring Security控制会话 ,需要的朋友可以参考下
    2019-05-05
  • Java中Stringbuild,Date和Calendar类的用法详解

    Java中Stringbuild,Date和Calendar类的用法详解

    这篇文章主要为大家详细介绍了Java中Stringbuild、Date和Calendar类的用法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-04-04
  • 如何自定义MyBatis拦截器更改表名

    如何自定义MyBatis拦截器更改表名

    自定义MyBatis拦截器可以在方法执行前后插入自己的逻辑,这非常有利于扩展和定制 MyBatis 的功能,本篇文章实现自定义一个拦截器去改变要插入或者查询的数据源 ,需要的朋友可以参考下
    2023-10-10
  • Spring MVC 中 AJAX请求并返回JSON的示例

    Spring MVC 中 AJAX请求并返回JSON的示例

    本篇文章主要介绍了Spring MVC 中 AJAX请求并返回JSON,具有一定的参考价值,有兴趣的可以了解一下。
    2017-01-01
  • SpringBoot整合redis+Aop防止重复提交的实现

    SpringBoot整合redis+Aop防止重复提交的实现

    Spring Boot通过AOP可以实现防止表单重复提交,本文主要介绍了SpringBoot整合redis+Aop防止重复提交的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 浅析Java NIO 直接缓冲区和非直接缓冲区

    浅析Java NIO 直接缓冲区和非直接缓冲区

    本篇文章主要为大家介绍了Java NIO 中直接缓冲区和非直接缓冲区的定义以及使用流程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • Java入门基础之抽象类与接口

    Java入门基础之抽象类与接口

    对于面向对象编程来说,抽象是它的一大特征之一,在 Java 中可以通过两种形式来体现OOP的抽象:接口和抽象类,下面这篇文章主要给大家介绍了关于Java入门基础之抽象类与接口的相关资料,需要的朋友可以参考下
    2022-02-02
  • java打印指定年月的日历

    java打印指定年月的日历

    这篇文章主要为大家详细介绍了Java如何打印指定年月的日历,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • Spring boot @ModelAttribute标注的实现

    Spring boot @ModelAttribute标注的实现

    这篇文章主要介绍了Spring boot @ModelAttribute标注的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01

最新评论