zoukankan      html  css  js  c++  java
  • Java多线程学习笔记——信号量的使用

    Java中在控制多线程访问资源的时候使用了信号量可以控制多个线程同时访问一个资源。

    有两个构造方法:

    public Semaphore(int permits)

    public Semaphore(int permits,boolean fair)

    第二个参数和重入锁一样,是指定是否公平。(公平是要牺牲性能的)

     1 public class SignalNum implements Runnable {
     2     Semaphore semaphore=new Semaphore(2);
     3 
     4 
     5     @Override
     6     public void run() {
     7         try {
     8             semaphore.acquire();
     9             for(int i=1;i<10;i++){
    10                 Thread.sleep(2000);
    11                 System.out.println(Thread.currentThread().getName()+":done"+i);
    12             }
    13 
    14             semaphore.release();
    15         } catch (InterruptedException e) {
    16             e.printStackTrace();
    17         }
    18     }
    19 
    20     public static void main(String[] args){
    21         SignalNum signalNum=new SignalNum();
    22         Thread t1=new Thread(signalNum,"t1");
    23         Thread t2=new Thread(signalNum,"t2");
    24         Thread t3=new Thread(signalNum,"t3");
    25 
    26         t1.start();
    27         t2.start();
    28         t3.start();
    29     }
    30 }

    这个例子的是指定了一次可以运行2的信号量,之后的执行结果为:

    D:Javajdk1.7.0_45injava -Didea.launcher.port=7535 "-Didea.launcher.bin.path=D:Program Files (x86)JetBrainsIntelliJ IDEA 15.0.4in" -Dfile.encoding=UTF-8 -classpath "D:Javajdk1.7.0_45jrelibcharsets.jar;D:Javajdk1.7.0_45jrelibdeploy.jar;D:Javajdk1.7.0_45jrelibextaccess-bridge-64.jar;D:Javajdk1.7.0_45jrelibextdnsns.jar;D:Javajdk1.7.0_45jrelibextjaccess.jar;D:Javajdk1.7.0_45jrelibextlocaledata.jar;D:Javajdk1.7.0_45jrelibextsunec.jar;D:Javajdk1.7.0_45jrelibextsunjce_provider.jar;D:Javajdk1.7.0_45jrelibextsunmscapi.jar;D:Javajdk1.7.0_45jrelibextzipfs.jar;D:Javajdk1.7.0_45jrelibjavaws.jar;D:Javajdk1.7.0_45jrelibjce.jar;D:Javajdk1.7.0_45jrelibjfr.jar;D:Javajdk1.7.0_45jrelibjfxrt.jar;D:Javajdk1.7.0_45jrelibjsse.jar;D:Javajdk1.7.0_45jrelibmanagement-agent.jar;D:Javajdk1.7.0_45jrelibplugin.jar;D:Javajdk1.7.0_45jrelib esources.jar;D:Javajdk1.7.0_45jrelib t.jar;E:JavaIDEATestJavaThreadout est est;D:Program Files (x86)JetBrainsIntelliJ IDEA 15.0.4libidea_rt.jar" com.intellij.rt.execution.application.AppMain SignalNum
    t1:done1
    t2:done1
    t1:done2
    t2:done2
    t1:done3
    t2:done3
    t1:done4
    t2:done4
    t1:done5
    t2:done5
    t1:done6
    t2:done6
    t1:done7
    t2:done7
    t1:done8
    t2:done8
    t1:done9
    t2:done9
    t3:done1
    t3:done2
    t3:done3
    t3:done4
    t3:done5
    t3:done6
    t3:done7
    t3:done8
    t3:done9

    Process finished with exit code 0

    我们可以看到t1 t2两个线程可以执行,然后t3等到了两个线程执行完成之后才能执行。

    信号量是用来同步数据的。

    然而在同时获得的资源会不会线程安全呢?我做了测试让3个线程同时获得资源然后各自加10000次,我发现了会有小于30000次的情况,说明同时获得资源的线程是线程不安全的,所以就算使用了信号量,还是要加锁。在这里我认为使用重入锁更加恰当,如果使用synchronized那么同时获得资源就没有意义了。

  • 相关阅读:
    Ajax学习总结
    从零开始学Docker
    IBM Websphere MQ常用命令及常见错误
    Log4j学习总结
    Eclipse中各图标含义
    类加载机制与反射
    Feign【入门】
    Eureka【故障演练分析】
    Eureka【启用https】
    Eureka【开启http basic权限认证】
  • 原文地址:https://www.cnblogs.com/Summer7C/p/5371664.html
Copyright © 2011-2022 走看看