I am doing a project on simulating a CPU job being processed. Basically the user will input a job with a length that will get processed and a priority key (from -20 to 19, starting at -20 for higher priority). So far I’ve gotten all of that to work, except for the program to terminate properly. Basically I need the program to terminate when all of the jobs in my priority queue have been processed. When each job gets processed, it will subtract from the length until it is 0. When it is 0, it will be removed from the priority queue. When there are no jobs remaining, (priority queue is empty), the program should terminate after inputting n for no new jobs. However for some reason, the way I have done out my code, it isn’t terminating. Rather, it is giving me a null pointer error when I input n when there are no jobs left to input. Can anyone point out to me where I may have possibly made an error? Thanks.
A sample input-output procedure would be the following with the following format (job name, length, priority):
Enter the job to be processed:
I:job1 3 0
O:job1Enter new job to be processed:
I:n
O:job1Enter new job to be processed:
I:job2 1 -3
O:job2Enter new job to be processed:
I:n
O:job1Enter new job to be processed:
I:n
This is my code:
import java.util.Scanner;
import java.lang.Integer;
public class PQScheduler {
String command = "";
String process = "";
String[] inputParts = null;
SLPQueue Q;
boolean empty = false;
PQScheduler(String inputCommand) {
Q = new SLPQueue();
Scanner comReader = new Scanner(System.in);
this.command = inputCommand;
this.inputParts = command.split("\\s"); // will split input at whitespace and store parts into array
while (empty == false) { // will loop until priority queue becomes empty
if (this.inputParts[0].equals("n")) { // input of no new jobs, will continue processing previous jobs however
if (Q.isEmpty()) {
System.exit(0);
}
else {
this.process(Q.entries.getHead(), Q.entries.getHead().getValue());
}
}
else {
int value = Integer.parseInt(inputParts[1]); // parses value of length into an integer
int key = Integer.parseInt(inputParts[2]); // parse value of key into an integer
try {
Q.insert(inputParts[0], key, value); // inserts job, length, and key into priority queue
} catch (InvalidKeyException e) {
e.printStackTrace();
}
this.process(Q.entries.getHead(), Q.entries.getHead().getValue()); // processes the highest priority job
}
System.out.println("Enter new job to be processed: ");
command = comReader.nextLine();
inputParts = command.split("\\s");
}
}
public void process(Node n, int value) {
if (value == 0) {
try {
Q.removeMin(); // removes the finished job
if (Q.isEmpty()) {
empty = true;
}
else {
process(Q.entries.getHead(), Q.entries.getHead().getValue()); // processes next highest priority job
}
} catch (EmptyPriorityQueueException e) {
e.printStackTrace();
}
}
else {
n.setValue(value - 1); // decrements job length by 1 when processed
process = n.getElement();
System.out.println(process);
}
}
public static void main(String[] args) {
String inputCommand = "";
Scanner mainReader = new Scanner(System.in);
System.out.println("Enter the job to be processed: "); // takes in user input of job, length, and priority
inputCommand = mainReader.nextLine();
PQScheduler scheduler = new PQScheduler(inputCommand);
}
}
public class SLPQueue implements PQueue {
protected SLList entries;
protected int size;
public SLPQueue() {
entries = new SLList(); // creates a new linked list to store elements
size = 0;
}
public String min() throws EmptyPriorityQueueException {
if(entries.isEmpty()) throw new EmptyPriorityQueueException("Priority Queue is empty.");
else
return entries.getHead().getElement(); // gets the first node in priority queue
}
public Node insert(String e, int k, int v) throws InvalidKeyException {
Node tempNode = new Node(e, k, v, null);
insertEntry(tempNode);
return tempNode; // insertion method to add values to node and then insert into priority queue
}
protected void insertEntry(Node n) { // insertion method to add into priority queue
if (entries.isEmpty()) { // checks if it is empty, if so, it will make it head of list
entries.addFirst(n);
size++;
}
else if (compare(n.getKey(), entries.getTail().getKey()) > 0) { // checks to see if lower priority key inserted
entries.addLast(n); // adds last if key inserted is lower priority than the current tail of list
size++;
}
else if (compare(n.getKey(), entries.getHead().getKey()) < 0) {
entries.addFirst(n); // adds first if key inserted is higher priority than the current head of list
size++;
}
else {
Node temp1 = entries.getHead(); // starts traversal from beginning of list
Node temp2 = temp1; // creates a second temporary node to "capture" node for node n to be inserted after
while (compare(n.getKey(), temp1.getKey()) > 0 ) { // loop to see if keys are of lower priority
if (temp1.equals(entries.getHead())) { // if statement created to set back temp2 by one node
temp1 = temp1.getNext();
}
else {
temp2 = temp2.getNext(); // gets the node value before temp1
temp1 = temp1.getNext(); // gets the next temp1 value
}
}
temp2.setNext(n); // loop will break when key has higher priority than temp1 key found
n.setNext(temp1);
size++;
}
}
public int compare(int k1, int k2) { // comparator method to check for key priorities
int compare = 0;
if (k1 >= k2) {
compare = 1; // returns 1 if first key is of lower priority than second key
}
else if (k1 < k2) { // returns -1 if first key is of higher priority than second key
compare = -1;
}
return compare;
}
public Node removeMin() throws EmptyPriorityQueueException { // removal method to remove from head of list
if (entries.isEmpty()) throw new EmptyPriorityQueueException("Priority Queue is empty.");
else {
return entries.removeFirst();
}
}
public int size() { // returns size of priority queue list
return size;
}
public boolean isEmpty() { // checks to see if priority queue list is empty
return size == 0;
}
}
I’m betting that
Q.isEmpty()isn’t behaving like you want it to. It looks like it’s operating on thesizeof the queue, but yourremoveMinmethod isn’t decrementing this value.Try adding
size--;to yourelseblock inSLPQueue.removeMin