Semaphore-信号量

2018-09-05  本文已影响0人  china_fuhai

Semaphore一个计数信号量。信号量维护了一个许可集合; 通过acquire()和release()来获取和释放访问许可证。只有通过acquire获取了许可证的线程才能执行,否则阻塞。通过release释放许可证其他线程才能进行获取。

公平性:没有办法保证线程能够公平地可从信号量中获得许可。也就是说,无法担保掉第一个调用 acquire()的线程会是第一个获得一个许可的线程。 如果第一个线程在等待一个许可时发生阻塞, 而第二个线程前来索要一个许可的时候刚好有一个许可被释放出来, 那么它就可能会在第一个线程之前获得许可。如果你想要强制公平,Semaphore 类有一个具有一个布尔类型的参数的构造子,通过这个参数以告知 Semaphore 是否要强制公平。强制公平会影响到并发性能,所以除非你确实需要它否则不要启用它。

package com.didispace;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * @author: Kevin
 * @官网: www.mimaxueyuan.com
 * @Q Q群:       660567408
 * @Email: mimaxueyuan@163.com
 * [每天进步一点点、人生带来大改变...]
 * [本代码对应视频地址:http://study.163.com/course/introduction/1004176043.htm]
 */
public class SemaphoreTest1 {

    public static void main(String[] args) {
        // 线程池
        ExecutorService exec = Executors.newCachedThreadPool();
        // 只能5个线程同时访问(设置许可证的数量),默认是不公平的
        //final Semaphore semp = new Semaphore(1);
        // 强制公平
        final Semaphore semp = new Semaphore(2);
        // 模拟多个客户端并发访问
        for (int index = 0; index < 5; index++) {
            Runnable run = () -> {
                try {
                    System.out.println(Thread.currentThread().getName() + "尝试获取许可证");
                    // 获取许可
                    semp.acquire();
                    System.out.println(Thread.currentThread().getName() + "获取许可证");
                    Thread.sleep(1000);
                    // 访问完后,释放 ,如果屏蔽下面的语句,则在控制台只能打印5条记录,之后线程一直阻塞
                    System.out.println(Thread.currentThread().getName() + "释放许可证");
                    semp.release();
                } catch (InterruptedException e) {
                }
            };
            exec.execute(run);
        }
        // 退出线程池
        exec.shutdown();
    }

}
上一篇 下一篇

猜你喜欢

热点阅读