Jesper
Jesper

Reputation: 2814

ArrayList returns 0 at every index

So I'm having a bit of trouble with this exercise. I solved one of the problems by synchronizing the arraylist in each thread, but there's still something wrong. The arraylist "data" is filled up with numbers from 0 to 9999. However, data.get(i); seems to be returning 0 at every single index, and i can't for the life of me figure out why. Here's the code:

private static int LIST_TRAVERSE_LIMIT = 10000; // size of problem

private boolean problem_3_failed = false; // set to true if failed

private List<Integer> data = new ArrayList<Integer>(); // data shared between threads, traversed and modified

private int negative_hits = 0; // counter for how many modifications are found during traversal

private void test_parallel_iteration() {
    for(int i=0; i<LIST_TRAVERSE_LIMIT; i++) data.add(i);
    // Define threads and run them
    Thread t1 = new Thread(() -> { // modify the list in just a few places
        synchronized(data){
            for(int i=0; i<LIST_TRAVERSE_LIMIT; i++) 
                if(data.get(i)%(LIST_TRAVERSE_LIMIT/3)==0) data.add(0, -data.get(i));
        }
    });
    Thread t2 = new Thread(() -> { // iterate the list
        try {
            synchronized(data){
                for(int i: data) 
                    if(i<0) {
                        System.out.println("Found negative number: "+i);
                        negative_hits++;
                    }
            }
        } catch(ConcurrentModificationException exn) {
            System.out.println("Problem 3, thread 2 failed: concurrent modification");
            problem_3_failed = true;
        }
    });
    finish(t1,t2);
    // What happened?
    System.out.println("#Negative hits: "+negative_hits);
    if(problem_3_failed) System.out.println("Problem 3 failed");
    else System.out.println("Problem 3 succeeded");
}

private void finish(Thread t1, Thread t2) {
    t1.start();
    t2.start();
    try {
        t1.join();
        t2.join();
    } catch (InterruptedException e) {
        throw new Error("Internal error: interrupted!");
    }
}

Output:

#Negative hits: 0
Problem 3 succeeded

Upvotes: 3

Views: 91

Answers (1)

nickb
nickb

Reputation: 59699

You're programming yourself into an infinite loop. Here's how:

Your list is a series of numbers from 0 - 10000, with i being the index into that list for the current element:

0 1 2 3 4 5 ...
^
i

When the condition data.get(i)%(LIST_TRAVERSE_LIMIT/3)==0 executes on the first element of the list (zero), the check succeeds. Then, you add an element at the beginning of the list, which is negative zero (still zero), and continue to the next element.

Now your List looks like this, but note what is at i:

0 0 1 2 3 4 ....
  ^
  i

So, it looks like every element is zero, because it is!

Upvotes: 7

Related Questions