多线程

Semaphore使用

2020-10-22  本文已影响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();
            }
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读