Semaphore使用

作者: 念䋛 | 来源:发表于2020-10-22 20:16 被阅读0次

    在spring cloud的hystrix组件中资源隔离分为线程池隔离和信号量,信号量底层用的就是Semaphore,下面分析Semaphore使用

    public class Semaphore1{
        public static void main(String[] args){
            ReentrantLock reentrantLock = new ReentrantLock();
            reentrantLock.lock();
            //分配2个信号量,不代表两个线程同时执行,因为一个线程可以拥有多个信号量
            Semaphore semaphore = new Semaphore(2);
            for(int i = 0; i < 10; i++){
                new Thread(new Task(semaphore),"threadname"+i).start();
            }
        }
        static class Task extends Thread{
            Semaphore semaphored;
            public Task(Semaphore semaphored){
                this.semaphored = semaphored;
            }
            @Override
            public void run(){
                try{
                    //获取信号量,默认是一个
                    semaphored.acquire();
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName());
                    //释放信号量,默认是一个
                    semaphored.release();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }
    
    public class Semaphore2{
        public static void main(String[] args){
            ReentrantLock reentrantLock = new ReentrantLock();
            reentrantLock.lock();
            //分配3个信号量,不代表3个线程同时执行,因为一个线程可以拥有多个信号量
            Semaphore semaphore = new Semaphore(3);
            for(int i = 0; i < 10; i++){
                new Thread(new Task(semaphore),"threadname"+i).start();
            }
        }
    
    
        static class Task extends Thread{
            Semaphore semaphored;
            public Task(Semaphore semaphored){
                this.semaphored = semaphored;
            }
            @Override
            public void run(){
                try{
                    //每次获取两个信号量
                    semaphored.acquire(2);
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName());
                    //获取信号量和释放信号量要保持一直,因为在AbstractQueuedSynchronizer类中维护了一个成员变量 state,这里为3,减去acquire中的入参和加release的入参,如果两个入参不一致,
                    // 减掉的和加上的数值不同,导致信号量前后不对等
                    semaphored.release(2);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
    
            }
        }
    }
    
    public class Semaphore3{
        public static void main(String[] args){
            ReentrantLock reentrantLock = new ReentrantLock();
            reentrantLock.lock();
            //分配3个信号量,不代表3个线程同时执行,因为一个线程可以拥有多个信号量
            Semaphore semaphore = new Semaphore(3);
            for(int i = 0; i < 10; i++){
                new Thread(new Task(semaphore),"threadname"+i).start();
            }
        }
        static class Task extends Thread{
            Semaphore semaphored;
            public Task(Semaphore semaphored){
                this.semaphored = semaphored;
            }
            @Override
            public void run(){
                try{
                    //返回是否有足够的信号量,并占用2个信号量,但是并不会阻塞其余信号量不足的线程
                    System.out.println(semaphored.tryAcquire(2));
                    Thread.sleep(1000);
                    //返还信号量
                    semaphored.release(2);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
    
            }
        }
    }
    
    public class Semaphore4{
        public static void main(String[] args){
            ReentrantLock reentrantLock = new ReentrantLock();
            reentrantLock.lock();
            //同一时间只允许3个线程执行
            Semaphore semaphore = new Semaphore(2);
            for(int i = 0; i < 10; i++){
                new Thread(new Task(semaphore), "threadname" + i).start();
            }
        }
    
        static class Task extends Thread{
            Semaphore semaphored;
    
            public Task(Semaphore semaphored){
                this.semaphored = semaphored;
            }
    
            @Override
            public void run(){
                try{
                    //判断是否有足够的信号量,如果没有则等待500毫秒,500毫秒以后返回fase,并不会占用信号量,如果信号量够用则占用两个信号量,一定要返还
                    if(semaphored.tryAcquire(2, 500, TimeUnit.MILLISECONDS)){
                        //这里最好用finally保证释放信号量
                        try{
                            Thread.sleep(1000);
                            System.out.println(Thread.currentThread().getName());
                        }finally{
                            //返还信号量
                            semaphored.release(2);
                        }
                    }else{
                        System.out.println(Thread.currentThread().getName() + "等待500毫秒之后取消等待");
                    }
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:Semaphore使用

        本文链接:https://www.haomeiwen.com/subject/kavpmktx.html