12-案例实现
案例实现
根据如下步骤来实现本案例:
1.创建一个 Event
类,指定该类实现一个 Comparable<Event>
接口:
public class Event implements Comparable<Event> {
2.声明一个整型私有字段 thread
。该字段用来存储创建事件的线程数:
private final int thread;
3.声明一个整型私有字段 priority
。该字段用来存储事件的优先级:
private final int priority;
4.实现该类的构造方法并初始化字段:
public Event(int thread, int priority) {
this.thread=thread;
this.priority=priority;
}
5.实现一个 getThread()
方法来返回 thread
字段:
public int getThread() {
return thread;
}
6.实现一个 getPriority()
方法来返回 priority
字段:
public int getPriority() {
return priority;
}
7.实现 compareTo()
方法。它以 Event
对象作为参数,并且把当前事件对象的优先级与参数的优先级进行比较。如果对象的优先级更高则返回−1,如果两者的优先级相同则返回0,如果对象的优先级更低则返回1。值得注意的是,该方法的实现正好与 Comparator.compareTo()
相反:
@Override
public int compareTo(Event e) {
if (this.priority > e.getPriority()) {
return -1;
} else if (this.priority<e.getPriority()) {
return 1;
} else {
return 0;
}
}
8.创建一个 Task
类并实现一个 Runnable
接口:
public class Task implements Runnable {
9.声明一个 int
型私有字段 id
来存储可以表明任务身份的数字:
private final int id;
10.声明一个 PriorityBlockingQueue<Event>
类型的私有字段 queue
,并用它存储任务生成的事件:
private final PriorityBlockingQueue<Event> queue;
11.实现该类的构造方法并初始化字段:
public Task(int id, PriorityBlockingQueue<Event> queue) {
this.id=id;
this.queue=queue;
}
12.实现 run()
方法。该方法把1000个事件存储在队列中,并且通过ID来区分创建事件的任务以及标记优先级范围为1~1000。使用 add()
方法来存储队列事件:
@Override
public void run() {
for (int i=0; i<1000; i++) {
Event event=new Event(id,i);
queue.add(event);
}
}
13.创建一个 Main
类,并添加一个 main()
方法:
public class Main {
public static void main(String[] args) {
14.创建一个 PriorityBlockingQueue<Event>
类型的 queue
对象:
PriorityBlockingQueue<Event> queue=new PriorityBlockingQueue<>();
15.创建一个有5个 Thread
对象的数组来存储线程对象并且分别执行5个作业:
Thread taskThreads[]=new Thread[5];
16.创建5个 Task
类型的对象。把新建的线程对象存入之前创建的数组中:
for (int i=0; i < taskThreads.length; i++) {
Task task=new Task(i, queue);
taskThreads[i]=new Thread(task);
}
17.启动早前已创建的5条线程:
for (int i=0; i < taskThreads.length; i++) {
taskThreads[i].start();
}
18.调用 join()
方法来等待5条线程执行完成:
for (int i=0; i < taskThreads.length; i++) {
try {
taskThreads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
19.在控制台打印队列的实际长度以及队列中存储的事件。使用 poll()
方法取出队列中的事件:
System.out.printf("Main: Queue Size: %d\n", queue.size());
for (int i=0; i<taskThreads.length * 1000; i++) {
Event event=queue.poll();
System.out.printf("Thread %s: Priority %d\n",
event.getThread(), event.getPriority());
}
20.在控制台打印队列的最终长度:
System.out.printf("Main: Queue Size: %d\n",queue.size());
System.out.printf("Main: End of the program\n");