上QQ阅读APP看书,第一时间看更新
1.1.7 公平与非公平信号量的测试
有些时候,获得许可的顺序与线程启动的顺序有关,这时信号量就要分为公平与非公平的。
所谓的公平信号量是获得锁的顺序与线程启动的顺序有关,但不代表100%地获得信号量,仅仅是在概率上能得到保证。而非公平信号量就是无关的了。
创建测试用的项目semaphoreFairTest,类MyService.java代码如下:
package myservice; import java.util.concurrent.Semaphore; public class MyService { private boolean isFair = false; private Semaphore semaphore = new Semaphore(1, isFair); public void testMethod() { try { semaphore.acquire(); System.out .println("ThreadName=" + Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } } }
类MyThread.java代码如下:
package extthread; import myservice.MyService; public class MyThread extends Thread { private MyService myService; public MyThread(MyService myService) { super(); this.myService = myService; } @Override public void run() { System.out.println("ThreadName=" + this.getName() + "启动了!"); myService.testMethod(); } }
类Run.java代码如下:
package test.run; import myservice.MyService; import extthread.MyThread; public class Run { public static void main(String[] args) { MyService service = new MyService(); MyThread firstThread = new MyThread(service); firstThread.start(); MyThread[] threadArray = new MyThread[4]; for (int i = 0; i < 4; i++) { threadArray[i] = new MyThread(service); threadArray[i].start(); } } }
程序运行后的效果如图1-15所示。
图1-15 乱序打印
非公平信号量运行的效果是线程启动的顺序与调用semaphore.acquire()的顺序无关,也就是线程先启动了并不代表先获得许可。
更改MyService.java类代码如下:
private boolean isFair = true;
程序运行结果如图1-16所示。
图1-16 有序打印
公平信号量运行的效果是线程启动的顺序与调用semaphore.acquire()的顺序有关,也就是先启动的线程优先获得许可。