1

I have a function which splits an array into smaller pieces.
Each piece is then evaluated in a separate thread.
The results are populated into a common list.

private void sortandkeep(int[] arr){
        traversed.add(arr);
        if(arr.length==1) return;
        List<Integer> layer=new ArrayList<Integer>();
        //Divide the layer into different parts for a barrier to be set up.
        //After the barrier is broken,the layer is added to the main list
        if(arr.length>4){
            List<int[]> parts=split(arr);//smaller split pieces are populated on the list
            CyclicBarrier barrier = new CyclicBarrier(parts.size());
            for(int[] e:parts){
                Thread t=new Thread(new sortingThread(barrier,e,layer));
                t.start();
            }
        }
        else
            .........
        //The main thread should not proceed,unless the above barrier is broken
        sortandkeep(toIntArray(layer));
    }

I would have expected the sortandkeep recursion to wait for the barrier to be broken.
This would happen when all the worker threads have invoked await.
However,this is not so.
The main thread keeps recursing - irrespective of the state of the worker threads. How is this so?

nosid
  • 48,932
  • 13
  • 112
  • 139
IUnknown
  • 9,301
  • 15
  • 50
  • 76
  • It would appear that what you need is a CountdownLatch not a CyclicBarrier. I don't see any need for the threads to wait for each other. – edharned Jul 02 '14 at 18:11
  • You say you would have expected sortandkeep to wait for the barrier, but your example does not show any call to barrier.await(). – Solomon Slow Jul 02 '14 at 19:57
  • Never the less, @edharned may have an insight into your problem. The purpose of CyclicBarrier is to insure that a group of threads all _start_ some new activity at the same time. If you want one thread to wait until all of the others have _finished_ something, then you can do as edharned suggested and use a CountdownLatch (workers call latch.countDown(), main calls latch.await()). Alternately, you could have the main thread join() each of the workers, but that's more lines of code because you'd need to keep references to all of the worker Threads in a container. – Solomon Slow Jul 02 '14 at 20:06

1 Answers1

1

If the main thread must wait for all the other threads to complete their tasks, then that thread is one of the parties which have to go through the barrier, and it must invoke await as well, before proceeding.

// [...]
    CyclicBarrier barrier = new CyclicBarrier(parts.size() + 1); // sorting threads AND main thread
    for(int[] e:parts){
        Thread t=new Thread(new sortingThread(barrier,e,layer));
        t.start();
    }
} else 
        // [...]
//The main thread should not proceed, unless the above barrier is broken
barrier.await();
sortandkeep(toIntArray(layer));
// [...]
didierc
  • 14,572
  • 3
  • 32
  • 52