美文网首页
基于CAS的一些锁(6)- Semaphore

基于CAS的一些锁(6)- Semaphore

作者: silence_J | 来源:发表于2020-05-09 11:55 被阅读0次
基本概念

Semaphore 信号标的意思,作用其实就是限流,构造方法中可以传一个参数permits表示允许同时执行线程的数量。也可看成是信号标、许可标记的数量。

semaphore.acquire()是阻塞方法,获取不到信号标就阻塞,获取到的话信号标permits会减1。

比如Semaphore semaphore = new Semaphore(1),一个线程semaphore.acquire()成功后,许可标记1会变成0,这时其它线程无法获得许可标记,acquire()方法会阻塞。当线程执行完后必须手动semaphore.release()释放标记,这时许可标记会从0变成1,其它线程acquire()到后可以继续执行。

举个栗子

举个例子,比如去窗口买票,new Semaphore(3)就表示有3个窗口,一个人抢先到了某个窗口前就表示acquire到了许可。3个窗口占满后别人只能等着,等有人买完票让出窗口release后才能占住窗口买票。

Semaphore默认是非公平的,new Semaphore(2, true) 第二个参数为true可设置成公平的。
公平就是有队列在那里等,需要执行的线程要先排队。用收费站来举例,假如有四辆车都在等着进一个车道,当后面再来一辆的时候,它不会超到前面去,而是要在后面排着,这叫公平。

内部实现公平锁用的AQS

所以说内部是有队列的。此外reentrantlock、CountDownLatch、CyclicBarrier、Phaser、ReadWriteLock、Semaphore、Exchanger都是用同一个队列,同一个类来实现的,这个类叫AQS。

示例程序
public class T06_Semaphore {

    public static void main(String[] args) {

        Semaphore semaphore = new Semaphore(2, true);
        // Semaphore semaphore = new Semaphore(1); // 允许一个线程同时执行

        new Thread(() -> {
            try {
                semaphore.acquire();
                System.out.println("thread1 start...");
                TimeUnit.SECONDS.sleep(1);
                System.out.println("thread1 end...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release();
            }
        }).start();

        new Thread(() -> {
            try {
                semaphore.acquire();
                System.out.println("thread2 start...");
                TimeUnit.SECONDS.sleep(1);
                System.out.println("thread2 end...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release();
            }
        }).start();
    }

}

相关文章

网友评论

      本文标题:基于CAS的一些锁(6)- Semaphore

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