15-案例实现
案例实现
根据以下步骤实现本案例。
1.创建 PrintQueue
类,并且通过该类实现打印队列:
public class PrintQueue {
2.在该类中声明一个类型为 Lock
的对象,并且在构造函数中用 ReentrantLock
初始化该对象。另外,该构造函数通过 Boolean
类型的参数指定 Lock
的公平策略:
private Lock queueLock;
public PrintQueue(bool fairMode) {
queueLock = new ReentrantLock(fairMode);
}
3.实现一个接收 Object
类型参数的 printJob()
方法。该方法不会返回任何值:
public void printJob(Object document){
4.在 printJob()
方法内部,通过 lock()
方法可获得 Lock
对象的控制权:
queueLock.lock();
5.通过以下代码来模拟打印文档的过程:
try {
Long duration=(long)(Math.random()*10000);
System.out.println(Thread.currentThread().getName()+ ":
PrintQueue: Printing a Job during "+
(duration/1000)+" seconds");
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
6.执行完上述代码后,通过 Lock
接口上的 unlock()
方法释放锁的控制权:
finally {
queueLock.unlock();
}
7.重复上述过程。 printJob()
方法将会获得并释放锁两次。通过这种特别的执行方式,你可以更好地理解公平锁和非公平锁间的区别。 printJob()
方法中的代码如下所示:
queueLock.lock();
try {
Long duration = (long) (Math.random() * 10000);
System.out.printf("%s: PrintQueue: Printing a Job during
%d seconds\n", Thread.currentThread()
.getName(),(duration / 1000));
Thread.sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
queueLock.unlock();
}
8.创建 Job
类——该类实现了 Runnable
接口:
public class Job implements Runnable {
9.在类中声明 PrintQueue
型的对象引用,并且在构造函数中完成初始化:
private PrintQueue printQueue;
public Job(PrintQueue printQueue){
this.printQueue=printQueue;
}
10.实现接口中的 run()
方法,该方法使用类中的 PrintQueue
对象传递一个打印任务:
@Override
public void run() {
System.out.printf("%s: Going to print a document\n",
Thread.currentThread().getName());
printQueue.printJob(new Object());
System.out.printf("%s: The document has been printed\n",
Thread.currentThread().getName());
}
11.通过实现一个名为 Main
的类和增加 main
()方法来生成主类:
public class Main {
public static void main (String args[]){
12.在 main()
函数之外实现其他辅助的方法用于测试 PrintQueue
类在不同公平锁策略下的表现,以保证 main()
方法的简洁性:
System.out.printf("Running example with fair-mode =
false\n");
testPrintQueue(false);
System.out.printf("Running example with fair-mode = true\n");
testPrintQueue(true);
}
13.在 testPrintQueue()
方法中创建一个共享的 PrintQueue
对象:
private static void testPrintQueue(Boolean fairMode) {
PrintQueue printQueue=new PrintQueue(fairMode);
14.创建10个线程并且在各自线程中执行 Job
对象的代码:
Thread thread[]=new Thread[10];
for (int i=0; i<10; i++){
thread[i]=new Thread(new Job(printQueue),"Thread "+ i);
}
15.启动10个线程:
for (int i=0; i<10; i++){
thread[i].start();
}
16.等待这10个线程全部运行完毕:
for (int i=0; i<10; i++) {
try {
thread[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}