Question

I'm trying to write a program to solve 2 puzzles who can't be solved independently from eachother, but have the same solution. My idea is that they both run in a seperate thread until they stop finding new pieces of information. Then they communicate what they have found by updating some shared state variables and continue if something was written by either one of them to the shared state.

I think a CyclicBarrier is the appropriate mechanism to use here. This is my code (which is running concurrently in 2 threads:

while (true) {

        doSolvingLogicHere();

        shareUpdates(); // this method updates the shared state variable and is synhronized

        int count;
        int updates = 0;
        try {
            count = writeBarrier.await();
            updates = threadsUpdatedSomething;
            if (count == 0) {
                writeBarrier.reset();
                threadsUpdatedSomething = 0; //'reset' the shared value
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BrokenBarrierException ex) {
            Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (updates == 0) { //no thread updated something
            break;
        } else { // at least one of the threads updated something, solving should continue in both threads
            readUpdates();
        }
}

ThreadsUpdatedSomething is a shared integer which is incremented in the 'ShareUpdates()' if anything at all was updated by the threads. When both threads didn't find anything new in the iteration, this means that they never will find anything new and the whole loop should be stopped for both threads. That's why I'm checking for it to be zero.

I would expect them to both stop when both threads did not write any new information in the shared state variables. But when running the program, one of the threads stop, while the other one keeps going. When debugging the program and setting breakpoints at 'readUpdates()' line, the program works as expected.

Is this the correct way for handling such a concurrent 'solving' loop? And in case it is correct, where is the error in my code?

Thanks for the help!

EDIT: Small mistake corrected. 'updates = threadsUpdatedSomething;' now at the correct place

Était-ce utile?

La solution

As per API , await returns

the arrival index of the current thread, where index getParties() - 1 indicates the first to arrive and zero indicates the last to arrive

 count = writeBarrier.await();

Being said , So only one of the Thread would receive the 0 . And only one thread would set the updates value to 0. Thats why the last arrived thread stopped and other one not stopped.

As per your statements , you need to stop the threads when you find both threads not updated the threadsUpdatedSomething. i assumed that time threadsUpdatedSomething would be zero. If not you have to change the logic , some how to find when the condition has to be break and apply it

while (true) {

        doSolvingLogicHere();

        shareUpdates(); // this method updates the shared state variable and is synhronized

        int count;
        int updates = 0;
        try {
             writeBarrier.await();
            if (threadsUpdatedSomething == 0) {
                updates = threadsUpdatedSomething;
                writeBarrier.reset();
                threadsUpdatedSomething -= 2; //'reset' the counter by decrementing 2
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BrokenBarrierException ex) {
            Logger.getLogger(TwinSolver.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (updates == 0) { //no thread updated something
            break;
        } else { // at least one of the threads updated something, solving should continue in both threads
            readUpdates();
        }
}

Also Don't forgot to set the break conditions in exception cases if required.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top