Java API提供的Lock接口实现ReentrantLock类还有一个带有boolean参数的构造方法,使用true作为参数就可以创建一个公平锁,使用公平锁时锁会选择等待时间最长的一个线程。
我们直接修改“Java并发编程初级篇(十三):使用锁来实现同步机制”的代码,使用公平锁替代非公平锁。
public class PrintQueue {
private Lock queueLock = new ReentrantLock(true);
public void printJob(Object document) {
queueLock.lock();
try {
long duration = (long)(Math.random() * 10000);
System.out.printf("%s: Print a Job during %d\n",
Thread.currentThread().getName(), duration / 1000);
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock();
}
}
}
每次创建线程间隔100毫秒 ,是为了基本保证线程可以按照创建顺序来竞争锁。
public class Main {
public static void main(String[] args) throws InterruptedException {
PrintQueue printQueue = new PrintQueue();
Job job = new Job(printQueue);
for (int i = 1; i <= 10; i++) {
Thread thread = new Thread(job);
thread.start();
Thread.sleep(100);
}
}
}
启动应用,查看控制台日志,你会发现线程是按照创建顺序来执行的。
Thread-0: Print a Job during 5
Thread-1: Print a Job during 8
Thread-2: Print a Job during 6
Thread-3: Print a Job during 6
Thread-4: Print a Job during 9
Thread-5: Print a Job during 2
Thread-6: Print a Job during 4
Thread-7: Print a Job during 9
Thread-8: Print a Job during 0
Thread-9: Print a Job during 2