Follow these steps to implement the example:
- Create a class named Event and specify that it implements the Comparable interface parameterized by the Event class:
public class Event implements Comparable<Event> {
- Declare a private int attribute named thread to store the number of threads that have created the event:
private final int thread;
- Declare a private int attribute named priority to store the priority of the event:
private final int priority;
- Implement the constructor of the class to initialize its attributes:
public Event(int thread, int priority){
this.thread=thread;
this.priority=priority;
}
- Implement the getThread() method to return the value of the thread attribute:
public int getThread() {
return thread;
}
- Implement the getPriority() method to return the value of the priority attribute:
public int getPriority() {
return priority;
}
- Implement the compareTo() method. It receives Event as a parameter and compares the priority of the current event and the one received as a parameter. It returns -1 if the priority of the current event is bigger, 0 if both the priorities are equal, and 1 if the priority of the current event is smaller. Note that this is the opposite of most Comparator.compareTo() implementations:
@Override
public int compareTo(Event e) {
if (this.priority>e.getPriority()) {
return -1;
} else if (this.priority<e.getPriority()) {
return 1;
} else {
return 0;
}
}
- Create a class named Task and specify that it implements the Runnable interface:
public class Task implements Runnable {
- Declare a private int attribute named id to store the number that identifies the task:
private final int id;
- Declare a private PriorityBlockingQueue attribute parameterized by the Event class named queue to store the events generated by the task:
private final PriorityBlockingQueue<Event> queue;
- Implement the constructor of the class to initialize its attributes:
public Task(int id, PriorityBlockingQueue<Event> queue) {
this.id=id;
this.queue=queue;
}
- Implement the run() method. It stores 1,000 events in the queue, using its ID, to identify the task that creates the event and we assign to each event a different priority from 1 to 1000. Use the add() method to store the events in the queue:
@Override
public void run() {
for (int i=0; i<1000; i++){
Event event=new Event(id,i);
queue.add(event);
}
}
- Implement the main class of the example by creating a class named Main and adding the main() method to it:
public class Main{
public static void main(String[] args) {
- Create a PriorityBlockingQueue object parameterized by the Event class named queue:
PriorityBlockingQueue<Event> queue=new PriorityBlockingQueue<>();
- Create an array of five Thread objects to store the threads that will execute the five tasks:
Thread taskThreads[]=new Thread[5];
- Create five Task objects. Store the threads in the array created earlier:
for (int i=0; i<taskThreads.length; i++){
Task task=new Task(i,queue);
taskThreads[i]=new Thread(task);
}
- Start the five threads created earlier:
for (int i=0; i<taskThreads.length ; i++) {
taskThreads[i].start();
}
- Wait for the finalization of the five threads using the join() method:
for (int i=0; i<taskThreads.length ; i++) {
try {
taskThreads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- Write the actual size of the queue in the console and the events stored in it. Use the poll() method to take off the events from the queue:
System.out.printf("Main: Queue Size: %d ",queue.size());
for (int i=0; i<taskThreads.length*1000; i++){
Event event=queue.poll();
System.out.printf("Thread %s: Priority %d ",
event.getThread(),event.getPriority());
}
- Write a message to the console with the final size of the queue:
System.out.printf("Main: Queue Size: %d ",queue.size());
System.out.printf("Main: End of the program ");