9

Ok so what I am trying to do here is to have a method "running" a process for a given amount of "time" this all seams to work to a degree but it keeps giveing these eceptions. This is the first execption it gives

     Exception in thread "main" java.util.ConcurrentModificationException

and then later on in the exicutio it gives this

    at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
at java.util.LinkedList$ListItr.next(LinkedList.java:696)
at parta.PartA.runQueueOne(PartA.java:273)

I dont know what I am doing wrong here am i supposed make this concurrent or something? If so how? I thought that linked list were synchronous by nature? maybe that where im getting this messed up.

Well any way here is the method that im usings:

public static void runQueueOne(LinkedList<MyProcess> q1, LinkedList<MyProcess> q2, LinkedList<MyProcess> q3, LinkedList<MyProcess> q4, int ct) {
    System.out.println("Running Level One Queue");


    for (MyProcess p : q1) {
        if (p.name.equalsIgnoreCase(q1.getFirst().name)) {
            //add 3 millsedonds to the service time
            q1.getFirst().serviceTimeTotal += 3;
            System.out.println(q1.getFirst().name + " is running");

        } else {
            //add 3 millseconds to wait time fr the un busy one
            p.waitTimeTotal += 3;
        }
    }

    for (MyProcess p : q2) {
        p.waitTimeTotal += 3;
    }
    for (MyProcess p : q3) {
        p.waitTimeTotal += 3;
    }
    for (MyProcess p : q4) {
        p.waitTimeTotal += 3;
    }

    //calculate all the priority
    for (MyProcess p : q1) {
        p.calculatePriority();
        switch (p.priority) {
            case 1:
                break;
            case 2:
                q1.remove(p);
                q2.add(p);
                break;
            case 3:
                q1.remove(p);
                q3.add(p);
                break;
            case 4:
                q1.remove(p);
                q4.add(p);
                break;
        }

    }
    ct += 3;
}

and here is where I call it in the main method

while (!allProcessDone) {
    //arrival queue
    for (MyProcess p : al) {
        addToQueue(qOne, p, currentTime);

        //cheack to see if all the processes are done
        if (p1.isDone == true &
                p2.isDone == true &
                p3.isDone == true &
                p4.isDone == true &
                p5.isDone == true &
                p6.isDone == true &
                p7.isDone == true &
                p8.isDone == true &
                p9.isDone == true &
                p10.isDone == true) {
            //end the loop
            allProcessDone = true;
            System.out.println("All proccess have been completed");
            break;
        }


        switch (robin) {
            case 1:
                runQueueOne(qOne, qTwo, qThree, qFour, currentTime);
                robin = 2;
                break;
            case 2:
                runQueueTwo(qOne, qTwo, qThree, qFour, currentTime);
                robin = 3;
                break;
            case 3:
                runQueueThree(qOne, qTwo, qThree, qFour, currentTime);
                robin = 4;
                break;
            case 4:
                runQueueFour(qOne, qTwo, qThree, qFour, currentTime);
                robin = 1;
                break;

        }
    }
Boken
  • 4,825
  • 10
  • 32
  • 42
MNM
  • 2,673
  • 6
  • 38
  • 73
  • 1
    I would use an ExecutorService which is built-in, thread safe, combines a Queue and a Thread Pool and allows you to obtain the results of individual tasks. – Peter Lawrey Oct 22 '12 at 14:33

2 Answers2

14

You are Concurrently accessing and modifying the Collection, that can't be done from for-each loop directly.

You have to use Iterator to solve this problem.

LinkedList<MyProcess> q1 = new LinkedList<MyProcess>();

Iterator<MyProcess> iterator = q1.iterator();

while (iterator.hasNext()){
     MyProcess mp = iterator.next();

     if (mp.name.equals("xyz")){
         iterator.remove();    // You can do the modification here.
     }
 }
Boken
  • 4,825
  • 10
  • 32
  • 42
Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
  • well I like this approach and I tried it but it still gives me the same errors `Iterator it = q1.iterator(); while(it.hasNext()) { MyProcess mp = it.next(); mp.calculatePriority(); switch(mp.priority) { case 1: break; case 2: q1.remove(mp); q2.add(mp); break; case 3: q1.remove(mp); q3.add(mp); break; case 4: q1.remove(mp); q4.add(mp); break; } } ` – MNM Oct 23 '12 at 13:06
  • Scratch that i got it to work I was not using the itorator.remove() function I was using the linked list one – MNM Oct 23 '12 at 13:44
  • @MNM I am glad that you did it, and you are most Welcome – Kumar Vivek Mitra Oct 23 '12 at 16:08
3

ConcurrentModificationException occurs when you try to remove an element from a List while you are iterating through it using a for loop.

I'm guessing your error is coming from these lines:

for (MyProcess p : q1) {
    p.calculatePriority();

    switch (p.priority) {
        case 1:
            break;
        case 2:
            q1.remove(p);
            q2.add(p);
            break;
        case 3:
            q1.remove(p);
            q3.add(p);
            break;
        case 4:
            q1.remove(p);
            q4.add(p);
            break;
    }
}

To fix the error, use iterator.remove() method

Boken
  • 4,825
  • 10
  • 32
  • 42
Kal
  • 24,724
  • 7
  • 65
  • 65