Java并发Semaphore信号量的学习

public class MyThreadTest {
    private final static Semaphore semaphore = new Semaphore(2);// 设置2个车位

    public static void main(String[] args) {
        System.out.println("start");

        p(semaphore, true, 1);
        p(semaphore, false, 1);
        p(semaphore, true, 2);
        p(semaphore, true, 3);
        p(semaphore, true, 4);
        p(semaphore, false, 3);

        System.out.println("end");
    }

    /**
     * 停车
     *
     * @param semaphore 信号对象
     * @param enterInto 停车true/出库false
     * @param theCarNum 车辆序号
     */
    private static void p(Semaphore semaphore, boolean enterInto, int theCarNum) {
        if (!enterInto) {
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("车辆出库");

            // 释放1个车位
            // 通过LockSupport.unpark(s.thread)来释放锁,详见AbstractQueuedSynchronizer.unparkSuccessor
            semaphore.release(1);
        }
        try {
            // 如果达到设定的信号量,通过LockSupport.park(this)来加锁,详见AbstractQueuedSynchronizer.parkAndCheckInterrupt
            semaphore.acquire();
            System.out.println("第 " + theCarNum + " 辆车进入");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     *     Semaphore中Sync继承了AbstractQueuedSynchronizer
     *     改变AbstractOwnableSynchronizer中state值(该值记录着剩余信号量)
     *
     *     AbstractQueuedSynchronizer加载时会调用静态代码块获取state的偏移地址:
     *     stateOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("state"));
     *     上述获取对象某个变量的效率比使用反射获取的效率高
     *
     *     protected final boolean compareAndSetState(int expect, int update) {
     *          // stateOffset为state变量的偏移地址
     *         return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
     *     }
     */

}

上述例子中我们可以发现,当停车位(信号量)用完时,就会进入到阻塞状态,即第四辆车进入等待状态。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值