zoukankan      html  css  js  c++  java
  • 21.Semaphore信号量

    Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。它的用法如下:

    • availablePermits() //用来获取当前可用的资源数量
    • wc.acquire(); //申请资源
    • wc.release();// 释放资源
    import java.util.Random;
    import java.util.concurrent.Semaphore;
    
    public class SemaphoreDemo implements Runnable{
        private String name;
        private Semaphore semaphore;
    
        public SemaphoreDemo(String name, Semaphore semaphore) {
            this.name = name;
            this.semaphore = semaphore;
        }
    
        @Override
        public void run() {
            try {
                //剩余的资源
                int i = semaphore.availablePermits();
                if (i > 0){
                    System.out.println(name+" 有资源了");
                }else {
                    System.out.println(name+" 没资源了");
                }
                semaphore.acquire();
                System.out.println(name+"资源到手");
                Thread.sleep(new Random().nextInt(1000));
                System.out.println(name+"好!!!");
                semaphore.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        public static void main(String[] args){
            Semaphore semaphore = new Semaphore(3);
            for (int i = 1; i <= 5; i++) {
                SemaphoreDemo demo = new SemaphoreDemo("第"+i+"个",semaphore);
                new Thread(demo).start();
            }
        }
        //第1个 有资源了
        //第1个资源到手
        //第2个 有资源了
        //第2个资源到手
        //第3个 有资源了
        //第3个资源到手
        //第4个 没资源了
        //第5个 没资源了
        //第2个好!!!
        //第4个资源到手
        //第1个好!!!
        //第5个资源到手
        //第3个好!!!
        //第4个好!!!
        //第5个好!!!
    }
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    
    /**
     * 信号量:允许多个线程同时访问
     * public  Semaphore(int permits)
     * public Semaphore(int permits,boolean fair) //第二参数可以指定是否公平
     */
    public class SemapDemo implements Runnable{
        final Semaphore semaphore = new Semaphore(5);//指定信号量的准入数
        @Override
        public void run() {
            try {
                semaphore.acquire();//尝试获取一个准入的许可,若无法获得,则线程会等待,直到有线程释放一个许可或当前线程被中断
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getId()+":done");
                semaphore.release();//线程访问资源结束后,释放一个许可
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        public static void main(String[] args){
            //线程池
            ExecutorService exec = Executors.newFixedThreadPool(20);
            final SemapDemo demo = new SemapDemo();
            for (int i = 0; i < 20; i++) {
                exec.submit(demo);
            }
        }
        //同时开启20个线程,系统以5个线程一组为单位,依次输出带有线程ID的提示文本
    }
    
  • 相关阅读:
  • 原文地址:https://www.cnblogs.com/fly-book/p/11400380.html
Copyright © 2011-2022 走看看