4

I have a simple multi threading problem (in Java). I have 2 sets of 4 very large arrays and I have 4 threads, 1 for each array in the set. I want the threads, in parallel, to check if both sets, if their arrays have identical values. If one of the values in one of the arrays does not match the corresponding index value in the other array, then the two sets are not identical and all threads should stop what they are doing and move on to next 2 sets of 4 very large arrays. This process continues until all the pairs of array sets have been compared and deemed equal or not equal. I want all the threads to stop when one of the threads finds a mis-match. What is the correct way to implement this?

  • Keep in mind that I want the most efficient solution. I want all the array set pairs to be compared with one another in the least amount of time. –  Apr 21 '15 at 05:45
  • Are they have to be arrays? I could imagine there are ways to index the array to speed up the comparison. – Kelvin Ng Apr 21 '15 at 12:09
  • Also, note that the element in array is not volatile http://stackoverflow.com/questions/2236184/how-to-declare-array-elements-volatile-in-java – Kelvin Ng Apr 21 '15 at 12:12

3 Answers3

1

Here's one simple solution, but I don't know if it's the most efficient: Simply declare an object with a public boolean field.

public class TerminationEvent {
    public boolean terminated = false;
}

Before starting the threads, create a new TerminationEvent object. Use this object as a parameter when you construct the thread objects, e.g.

public class MyThread implements Runnable {
    private TerminationEvent terminationEvent;
    public MyThread(TerminationEvent event) {
        terminationEvent = event;
    }
}

The same object will be passed to every MyThread, so they will all see the same boolean.

Now, the run() method in each MyThread will have something like

if (terminationEvent.terminated) {
    break;
}

in the loop, and will set terminationEvent.terminated = true; when the other threads need to stop.

(Normally I wouldn't use public fields like terminated, but you said you wanted efficiency. I think this is a bit more efficient than a getter method, but I haven't tried benchmarking anything. Also, in a simple case like this, I don't think you need to worry about synchronization when the threads read or write the terminated field.)

ajb
  • 31,309
  • 3
  • 58
  • 84
0

Stopping other threads are usually done through the use of interrupts. Java threads do no longer use Thread.stop() because this was seen as unsafe in that it unlocks all monitors held by the thread, possibly leading to other threads being able to view objects in an inconsistent state (Ref: http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html). The threads are not "stopped" as such, but are commonly used to set a flag false:

The thread should check the interrupted flag (infrequently) before performing computations:

if (Thread.interrupted()) {
    throw new InterruptedException();
}
EvenLisle
  • 4,672
  • 3
  • 24
  • 47
  • That may be one solution, but I doubt that it's the way it's "usually" done. – ajb Apr 21 '15 at 05:46
  • But then each of the threads will have to poll to see if an interrupt occurred. The more time the threads spend polling, the fewer comparisons they get done. –  Apr 21 '15 at 05:47
  • Is there a more efficient solution than making each thread poll after every X comparisons? –  Apr 21 '15 at 05:48
  • I'm afraid Java does not currently offer any (safe) alternatives. However, checking every - say - 10 comparisons is not a major performance hit. I agree it looks suboptimal, but at least it is a safe way that guarantees runtime consistency. – EvenLisle Apr 21 '15 at 05:54
  • 1
    @SachaTRed There's no answer that doesn't involve some kind of polling. – ajb Apr 21 '15 at 05:56
  • @ajb - That was all I needed to know. Thank you. –  Apr 21 '15 at 15:26
0

Use a volatile variable to set the abort condition. In your check loop that is run by all threads, let those threads check a number N of values uninterrupted so they don't have to fetch the volatile too often, which may be costly compared to the value match test. Benchmark your solution to find the optimum for N on your target hardware.

Another way would be to use a ForkJoin approach where your result is true if a mismatch was found. Divide your array slices down to a minimum size similar to N.

Ralf H
  • 1,392
  • 1
  • 9
  • 17