zoukankan      html  css  js  c++  java
  • 并发编程 Semaphore的使用和详解

    类Semaphore的基本使用

    Semaphore的作用:限制线程并发的数量

    课外话题【多线程的同步概念】:其实就是排着队去执行一个任务,执行任务是一个一个的执行,这样的优点是有助于程序逻辑的正确性,不会出现非线程安全问题,保证人系统功能的运行稳定。

    Semaphore类结构图:

    1、类Semaphore的构造函数permits 是许可的意思,代表同一时间,最多允许permits执行acquire() 和release() 之间的代码。
    例如:

    Semaphore semaphore = new Semaphore(1);

    表示同一时间内最多只允许1个线程执行 acquire()和release()之间的代码。
    2、方法acquire(n) 的功能是每调用1次此方法,就消耗掉n个许可。
    3、方法release(n) 的功能是每调用1次此方法,就动态添加n个许可。
    4、方法acquireUnnterruptibly()作用是是等待进入acquire() 方法的线程不允许被中断。
    5、方法availablePermits() 返回Semaphore对象中当前可以用的许可数。
    6、方法drainPermits() 获取并返回所有的许可个数,并且将可用的许可重置为0
    7、方法 getQueueLength() 的作用是取得等待的许可的线程个数
    8、方法 hasQueueThreads() 的作用是判断有没有线程在等待这个许可
    9、公平和非公平信号量:
    有些时候获取许可的的顺序与线程启动的顺序有关,这是的信号量就要分为公平和非公平的。所谓的公平信号量是获得锁的顺序与线程启动的顺序有关,但不代表100%获得信号量,仅仅是在概率上能保证,而非公平信号量就是无关的。
    例如:

    Semaphore semaphore = new Semaphore(1false);

    False:表示非公平信号量,即线程启动的顺序与调用semaphore.acquire() 的顺序无关,也就是线程先启动了并不代表先获得 许可。
    True:公平信号量,即线程启动的顺序与调用semaphore.acquire() 的顺序有关,也就是先启动的线程优先获得许可
    10、方法tryAcquire() 的作用是尝试获取1个许可。如果获取不到则返回false,通常与if语句结合使用,其具有无阻塞的特点。无阻塞的特点可以使不至于在同步处于一直持续等待的状态。
    11、方法tryAcquire(n) 的作用是尝试获取n个许可,如果获取不到则返回false
    12、方法tryAcquire(long timeout,TimeUnit unit)的作用是在指定的时间内尝试获取1个许可,如果获取不到则返回false
    13、方法tryAcquire(int permits,long timeout,TimeUnit unit) 的作用是在指定的时间内尝试获取n 个许可,如果获取不到则返回false
    14、多进路-多处理-多出路:允许多个线程同时处理任务
    例如:

    public class MyService {
        
        private Semaphore semaphore = new Semaphore(3);
        private Lock lock = new ReentrantLock();
        
        public void testMethod(){
            try
            {
                semaphore.acquire();
                //synchronized (this) 
                //{
                    //lock.lock();
                    System.out.println(Thread.currentThread().getName()+" 开始时间:"+System.currentTimeMillis());
                    for(int i = 0; i < 10; i++){
                        System.out.println(Thread.currentThread().getName()+"打印"+ (i+1)+"");
                    }
                    System.out.println(Thread.currentThread().getName()+" 结束时间: "+System.currentTimeMillis());
                    //lock.unlock();
                //}
                
                semaphore.release();
            }
            catch(Exception e)
            {
                
            }
        }
    }

    运行的效果是多个线程同时进入。并且多个线程有几乎同时执行完毕。

    15、多进路-单处理-多出路:允许多个线程同时处理任务,但是顺序却是同步的,也就是阻塞的。所以也称单处理。

    例如:在代码中加入ReentrantLock对象 ,或者使用synchronized 代码块,保存代码的同步性

    public class MyService {
        
        private Semaphore semaphore = new Semaphore(3);
        private Lock lock = new ReentrantLock();
        
        public void testMethod(){
            try
            {
                semaphore.acquire();
                synchronized (this) 
                {
                    //lock.lock();
                    System.out.println(Thread.currentThread().getName()+" 开始时间:"+System.currentTimeMillis());
                    for(int i = 0; i < 10; i++){
                        System.out.println(Thread.currentThread().getName()+"打印"+ (i+1)+"");
                    }
                    System.out.println(Thread.currentThread().getName()+" 结束时间: "+System.currentTimeMillis());
                    //lock.unlock();
                }
                semaphore.release();
            }
            catch(Exception e)
            {    
            }
        }
    }

    1.2Exchanger的使用

    作用:可以是2个线程之间传输数据

    1、 方法exchange() 方法具有阻塞的特色,也就是此方法被调用后等待其他线程来取得数据,如果没有,则一直等待。

     

     

  • 相关阅读:
    做最简单的自定义控件!
    DataGridView取消默认选中行
    好看的vs皮肤
    rdlc插入图像(.net2010)
    学习c#反射的一个例子
    C#Winform中ToolTip的简单用法
    rdlc报表显示条码 .
    vb.net ctype用法
    一些常用的正则表达式 .
    C# WinForm中MenuStrip动态菜单使用总结
  • 原文地址:https://www.cnblogs.com/wujiaofen/p/11356436.html
Copyright © 2011-2022 走看看