Java线程--Semaphore使用

原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11872132.html

Java线程--Semaphore使用

Semaphore是信号量, 也叫许可证管理器, 类似于取票窗口, 办事窗口, 打饭窗口等等这种情况, 只有排队等到了这样才算拿到了信号量, 拿到了许可证 .

package concurrent.semaphore;

import java.util.concurrent.Semaphore;

/**
 * 信号量 , 许可证管理器 main 测试类
 */
public class MainTest {

    public static void main(String[] args) throws InterruptedException {
        /**
         * 定义2个取票窗口, 公平的排队取票
         */
        Semaphore ticketWindow = new Semaphore(2, true);
        Thread[] threads = new Thread[10];
        for (int i = 0 ; i < 30; i++) {
            /**
             * 前面十个小伙伴坚持排队
             */
            if (i < 10) {
                new Thread(new Man("坐火车良民" + i, ticketWindow, 0)).start();
            } else if (i >= 10 && i < 20) {
                /**
                 * 这5个小伙伴没有耐心,只会等1毫秒
                 */
                new Thread(new Man("坐飞机良民" + i, ticketWindow, 1)).start();
            } else {
                /**
                 * 这5个小伙伴没有耐心
                 */
                threads[i - 20] = new Thread(new Man("回家吃饭良民" + i, ticketWindow, 2));
                threads[i - 20].start();
            }
        }

        Thread.sleep(2000);
        for (int i = 0; i < 5; i++) {
            threads[i].interrupt();
        }
    }

    void show(){
        /**
         * 初始化许可证数量, 5个许可证/信号量, 公平模式
         */
        Semaphore semaphore = new Semaphore(5, true);
        try {
            /**
             * 获取一个许可证/信号量
             * 此线程会一直阻塞,直到获取这个许可证,或者被中断(抛出InterruptedException异常)
             */
            semaphore.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /**
         * 释放一个许可证/信号量
         */
        semaphore.release();
        try {
            /**
             * 获取3个许可证/信号量
             * 此线程会一直阻塞,直到获取这个许可证,或者被中断(抛出InterruptedException异常)
             */
            semaphore.acquire(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /**
         * 释放3个许可证/信号量
         */
        semaphore.release(3);
        /**
         * 是否有正在等待许可证的线程
         */
        semaphore.hasQueuedThreads();
        /**
         * 正在等待许可证的队列长度(线程数量)
         */
        semaphore.getQueueLength();
        /**
         * 剩余许可证的数量
         */
        semaphore.drainPermits();
        /**
         * 尝试获取, 获取不到就返回false
         */
        semaphore.tryAcquire();
        /**
         * 获取的时候无法被打断
         */
        semaphore.acquireUninterruptibly();
    }
}
package concurrent.semaphore;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * 排队取票的人
 */
public class Man implements Runnable {

    /**
     * 取票的人的姓名
     */
    private String name;
    /**
     * 必须要的取票证明
     */
    private Semaphore semaphore;
    /**
     * 最后的行为
     * 0 : 取到票为止
     * 1 : 排队的时候不耐烦, 走了, 买飞机票去了
     * 2 : 排队的时候突然有事, 回家去了
     */
    private int behav;

    public Man(String name, Semaphore semaphore, int behav) {
        this.name = name;
        this.semaphore = semaphore;
        this.behav = behav;
    }


    @Override
    public void run() {
        switch (behav) {
            /**
             * 坚持到底
             */
            case 0 :
                /**
                 * 排队, 坚持不懈 , 就是要拿到许可证
                 */
                semaphore.acquireUninterruptibly();
                try {
                    Thread.sleep(1000);
                    System.out.println("我正在取票啦!!  " + name);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                semaphore.release();
                System.out.println("哇, 我终于取到票啦!!  " + name);
                break;
            /**
             * 买不到我就坐飞机
             */
            case 1 :
                try {
                    if (semaphore.tryAcquire(1, TimeUnit.SECONDS)) {
                        System.out.println("我正在取票啦!!  " + name);
                        Thread.sleep(2000);
                        semaphore.release();
                        System.out.println("哇, 我终于取到票啦!!  " + name);
                    } else {
                        System.out.println("我不取了, 坐飞机去啦!!  " + name);
                    }
                    break;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                /**
             * 买不到我就回家
             */
            case 2 :
                try {
                    semaphore.acquire();
                    try {
                        Thread.sleep(1000);
                        System.out.println("我正在取票啦!!  " + name);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    semaphore.release();
                    System.out.println("哇, 我终于取到票啦!!  " + name);
                } catch (InterruptedException e) {
                    //e.printStackTrace();
                    System.out.println("算了, 回家吃饭去了 "  + name);
                }
                break;
            /**
             * 不知道这个人是干嘛的, 黄牛吧
             */
            default:
                break;
        }
    }
}

打印如下:

我正在取票啦!!  坐火车良民0
我正在取票啦!!  坐火车良民1
哇, 我终于取到票啦!!  坐火车良民0
哇, 我终于取到票啦!!  坐火车良民1
我不取了, 坐飞机去啦!!  坐飞机良民10
我不取了, 坐飞机去啦!!  坐飞机良民17
我不取了, 坐飞机去啦!!  坐飞机良民19
我不取了, 坐飞机去啦!!  坐飞机良民16
我不取了, 坐飞机去啦!!  坐飞机良民13
我不取了, 坐飞机去啦!!  坐飞机良民15
我不取了, 坐飞机去啦!!  坐飞机良民14
我不取了, 坐飞机去啦!!  坐飞机良民12
我不取了, 坐飞机去啦!!  坐飞机良民11
我不取了, 坐飞机去啦!!  坐飞机良民18
我正在取票啦!!  坐火车良民3
哇, 我终于取到票啦!!  坐火车良民3
我正在取票啦!!  坐火车良民2
哇, 我终于取到票啦!!  坐火车良民2
算了, 回家吃饭去了 回家吃饭良民20
算了, 回家吃饭去了 回家吃饭良民23
算了, 回家吃饭去了 回家吃饭良民22
算了, 回家吃饭去了 回家吃饭良民24
算了, 回家吃饭去了 回家吃饭良民21
我正在取票啦!!  坐火车良民4
哇, 我终于取到票啦!!  坐火车良民4
我正在取票啦!!  坐火车良民5
哇, 我终于取到票啦!!  坐火车良民5
我正在取票啦!!  坐火车良民6
哇, 我终于取到票啦!!  坐火车良民6
我正在取票啦!!  坐火车良民7
哇, 我终于取到票啦!!  坐火车良民7
我正在取票啦!!  坐火车良民8
哇, 我终于取到票啦!!  坐火车良民8
我正在取票啦!!  坐火车良民9
哇, 我终于取到票啦!!  坐火车良民9
我正在取票啦!!  回家吃饭良民25
哇, 我终于取到票啦!!  回家吃饭良民25
我正在取票啦!!  回家吃饭良民26
哇, 我终于取到票啦!!  回家吃饭良民26
我正在取票啦!!  回家吃饭良民29
哇, 我终于取到票啦!!  回家吃饭良民29
我正在取票啦!!  回家吃饭良民27
哇, 我终于取到票啦!!  回家吃饭良民27
我正在取票啦!!  回家吃饭良民28
哇, 我终于取到票啦!!  回家吃饭良民28

猜你喜欢

转载自www.cnblogs.com/fanerwei222/p/11872132.html