使用Semaphore构建一个显示锁
package com.dwz.utils; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class SemaphoreExample1 { public static void main(String[] args) { final SemaphoreLock lock = new SemaphoreLock(); for(int i = 0; i < 2; i++) { new Thread() { public void run() { try { System.out.println(Thread.currentThread().getName() + " is Running."); lock.lock(); System.out.println(Thread.currentThread().getName() + " get the #SemaphoreLock."); TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } System.out.println(Thread.currentThread().getName() + " released the #SemaphoreLock."); }; }.start(); } } static class SemaphoreLock { private final Semaphore semaphore = new Semaphore(1); public void lock() throws InterruptedException { semaphore.acquire(); } public void unlock() { semaphore.release(); } } }
结果:
Thread-0 is Running. Thread-1 is Running. Thread-0 get the #SemaphoreLock. Thread-0 released the #SemaphoreLock. Thread-1 get the #SemaphoreLock. Thread-1 released the #SemaphoreLock.
演示semaphore的两种方法:
availablePermits():返回当前可使用的许可证数量
getQueueLength():返回当前正在等待获取许可证的线程数量
package com.dwz.utils; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class SemaphoreExample2 { public static void main(String[] args) throws InterruptedException { Semaphore semaphore = new Semaphore(2); for(int i = 0; i < 2; i++) { new Thread() { public void run() { System.out.println(Thread.currentThread().getName() + " in."); try { semaphore.acquire(); System.out.println(Thread.currentThread().getName() + " get the semaphore."); TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } System.out.println(Thread.currentThread().getName() + " out."); }; }.start(); } while(true) { System.out.println("AP->" + semaphore.availablePermits()); System.out.println("QL->" + semaphore.getQueueLength()); TimeUnit.SECONDS.sleep(1); } } }
演示当前的许可证都被使用后,其它线程处于等待状态并且被打断,
演示acquireUninterruptibly()对interrupt()的中断信号置之不理
package com.dwz.utils; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class SemaphoreExample3 { public static void main(String[] args) throws InterruptedException { final Semaphore semaphore = new Semaphore(1); Thread t1 = new Thread() { public void run() { try { semaphore.acquire(); TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } System.out.println("T1 finished."); }; }; t1.start(); TimeUnit.MILLISECONDS.sleep(50); Thread t2 = new Thread() { public void run() { try { semaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } System.out.println("T2 finished."); }; }; t2.start(); Thread t3 = new Thread() { public void run() { //对interrupt()的中断信号置之不理 semaphore.acquireUninterruptibly(); System.out.println("T3 finished."); }; }; t3.start(); TimeUnit.MILLISECONDS.sleep(50); t2.interrupt(); t3.interrupt(); } }
测试结果:
java.lang.InterruptedException T3 finished. T2 finished. at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304) at java.util.concurrent.Semaphore.acquire(Semaphore.java:312) at com.dwz.utils.SemaphoreExample3$2.run(SemaphoreExample3.java:30) T1 finished.
结果表明interrupt()打断的是acquire()