0

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");
    }
3
  • Synchronize the method(s) that access the data Commented Jan 17, 2013 at 5:26
  • It appears that your for loop should only be an if check? List<BigInteger> list = myMap.get(FirstModulus); if (list == null) { list = new ArrayList<BigInteger>(); myMap.put(FirstModulus, list); } list.add(gcd); (this eliminates the need for the if (myMap.size() > 0) { ... } else { ... } and makes it a bit more readable) Commented Jan 17, 2013 at 6:08
  • Have a look at thread communication discussions like this one stackoverflow.com/questions/12274821/… Commented Jan 17, 2013 at 6:19

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. the boolean flag works inside each thread? where should check the condition?
0
          //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());
            }
}

Comments

0

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.

2 Comments

The same issue relates to this as Quoi's solution.
Join waits for the thread to die. How do I know when all the thread finished.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.