John
John

Reputation: 837

Multiple threads and Synchronization in Java

I'm working on a multithreaded program where each thread calculates the GCD for two numbers, stores the numbers and GCD into a TreeMap, and prints out the TreeMap after all the threads finish. What kind of method should I use to make sure that only one thread is storing the data at the same time, and how do I use the last thread to print the TreeMap when it is ready to print?

for (int i = 0; i < myList.size(); ++i) {
    for (int j = i + 1; j < myList.size(); ++j) {
        modulus1 = myList.get(i);
        modulus2 = myList.get(j);
        pool.execute(new ThreadProcessRunnable(modulus1, modulus2, myMap));
    }
}

public void run() {
    ThreadProcess process = null;
    try {
        // Only one thread should execute the following code
        for (Map.Entry<BigInteger, ArrayList<BigInteger>> entry : myMap.entrySet()) {
            System.out.println("key ->" + entry.getKey() + ", value->" + entry.getValue());
        }
    } catch (Exception e) {
        System.err.println("Exception ERROR");
    }

Upvotes: 0

Views: 1413

Answers (3)

sujith
sujith

Reputation: 2421

You can use Collections.synchronizedMap to make it thread safe. And use thread.join to make sure printing is done only when all threads are dead.

Edit: Do the printing in Main thread. Just before printing, call join on all threads.

Upvotes: 0

Andrey Atapin
Andrey Atapin

Reputation: 7935

You must use syncronize(myMap) {...} block in places where you need to guarantee single thread access to the map.

As for printing the result by the last thread, you can use a boolean flag as a signal of completeness and check it every time. Don't forget to make it volatile to let each thread see its value changes.

UPD: Brian Goetz "Java Concurrency In Practice" is a strongly recommended reading.

Upvotes: 1

TheWhiteRabbit
TheWhiteRabbit

Reputation: 15758

          //Only one thread should executes the following code
synchronize{            
for (Map.Entry<BigInteger, ArrayList<BigInteger>> entry : myMap.entrySet()) {
                System.out.println("key ->" + entry.getKey() + ", value->" + entry.getValue());
            }
}

Upvotes: 0

Related Questions