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);
* }
*/
}
上述例子中我们可以发现,当停车位(信号量)用完时,就会进入到阻塞状态,即第四辆车进入等待状态。