[concurrency-interest] ThreadPoolExecutorTestoccasionallyfailswith a broken barrier!?

Oliver Pfeiffer pfeiffer at tzi.de
Wed Feb 14 03:14:44 EST 2007


The barrier should check that a total number of 17 threads (16 + 1) are able
to touch it in parallel. Thus all further threads arriving later do not need
to pass the barrier.

The occasionally thrown AssertionError comes from the broken barrier as
checked by assertFalse(barrier.isBroken()); at the end of the test method.

Future#get() isn't called after submission since an exception should never
be thrown in the runnable as long as latch#countDown() is harmless. :)

Oliver

> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu 
> [mailto:concurrency-interest-bounces at cs.oswego.edu] On Behalf 
> Of Joe Bowbeer
> Sent: Wednesday, February 14, 2007 4:38 AM
> To: concurrency-interest at cs.oswego.edu
> Subject: RE: [concurrency-interest] 
> ThreadPoolExecutorTestoccasionallyfailswith a broken barrier!?
> 
> 
> I got this far with my analysis:
> 
> It looks like all 16 pool threads will wait on the barrier, 
> the main thread (caller) will wait on the 17th submission, 
> and then none of the remaining executions will wait on the barrier.
> 
> There are several assertions that can fail.  Which one or 
> ones are failing? 
> 
> Btw, why not just execute these runnables?  I hate for good 
> futures (created by submit) to be wasted.. and they can 
> swallow errors.
> 
> 
> On 2/13/07, _David Holmes_ <<dcholmes at optusnet.com.au>> wrote:
> 
> > Oops - my mistake. Thanks Joe.
> >  
> > But now the logic of comparing the count to getParties doesn't make 
> > sense to me.
> >  
> > The barrier will break if a thread times out, so that is 
> what should 
> > be checked for - the reason for the broken barrier. The 
> next step is 
> > to determine why it timed out.
> >  
> > David
> > 
> > > -----Original Message-----
> > > _From: concurrency-interest-bounces at cs.oswego.edu>
> > > [mailto:<concurrency-interest-bounces at cs.oswego.edu>]_On 
> Behalf Of 
> > > _Joe Bowbeer _Sent:_ Wednesday, 14 February 2007 1:06 PM
> > > _To: concurrency-interest at cs.oswego.edu>
> > > 
> > > _Subject:_ Re: [concurrency-interest] ThreadPoolExecutorTest 
> > > occasionallyfailswith a broken barrier!?
> > > 
> > > but getParties returns parties, which is final...
> > > 
> > > On 2/13/07, _David Holmes_ <<dcholmes at optusnet.com.au>> wrote:
> > > 
> > > > Oliver,
> > > > 
> > > > You have a race condition testing the count against the barrier 
> > > > parties. Between the change of the count and the test of 
> > > > getParties() other threads
> > > > could have hit the barrier. As a result the current 
> thread doesn't
> > > > wait on
> > > > the barrier, and as a result of that any threads already at the
> > > > barrier will
> > > > eventually timeout, hence the broken barrier.
> > > > 
> > > > David Holmes
> > > > 
> > > > > -----Original Message-----
> > > > > From: <concurrency-interest-bounces at cs.oswego.edu>
> > > > > [mailto:<concurrency-interest-bounces at cs.oswego.edu>]On Behalf
> > > > Of Oliver
> > > > > Pfeiffer
> > > > > Sent: Wednesday, 14 February 2007 8:22 AM
> > > > > To: <concurrency-interest at cs.oswego.edu>
> > > > > Subject: [concurrency-interest] ThreadPoolExecutorTest
> > > > occasionally
> > > > > failswith a broken barrier!?
> > > > >
> > > > >
> > > > > Hi,
> > > > >
> > > > > I'm wondering why the given JUnit test (shown below)
> > > > occasionally
> > > > > fails with
> > > > > a broken barrier on multi processor systems using Java 5. The
> > > > repetitive
> > > > > test fails 27 times of 10.000 runs on my dual-core system. The
> > > > test should
> > > > > check wheter the acquired maximum number of simultaneous pool
> > > > threads are
> > > > > usable and that the pool doesn't fail even when the internal
> > > > task queue is
> > > > > full (caller runs policy).
> > > > >
> > > > > Greetings
> > > > >  Oliver
> > > > >
> > > > > =====================
> > > > >
> > > > > import java.util.concurrent.CountDownLatch;
> > > > > import java.util.concurrent.CyclicBarrier ;
> > > > > import java.util.concurrent.SynchronousQueue;
> > > > > import java.util.concurrent.ThreadPoolExecutor;
> > > > > import java.util.concurrent.TimeUnit;
> > > > > import java.util.concurrent.atomic.AtomicInteger;
> > > > >
> > > > > import junit.extensions.RepeatedTest;
> > > > > import junit.framework.Test;
> > > > > import junit.framework.TestCase;
> > > > >
> > > > > public class ThreadPoolExecutorTest extends TestCase {
> > > > >
> > > > >   private static final ThreadPoolExecutor 
> THREAD_POOL_EXECUTOR =
> > > > >     new ThreadPoolExecutor(
> > > > >       0, 16, 10, TimeUnit.SECONDS,
> > > > >       new SynchronousQueue<Runnable>(),
> > > > >       new ThreadPoolExecutor.CallerRunsPolicy()
> > > > >     );
> > > > >
> > > > >   public ThreadPoolExecutorTest(String name) {
> > > > >     super(name);
> > > > >   }
> > > > >
> > > > >   public static Test suite() {
> > > > >     return new RepeatedTest(
> > > > >       new ThreadPoolExecutorTest("testThreadPoolExecutor"),
> > > > 10000
> > > > >     );
> > > > >   }
> > > > >
> > > > >   public void testThreadPoolExecutor() throws
> > > > InterruptedException {
> > > > >     final int threads =
> > > > THREAD_POOL_EXECUTOR.getMaximumPoolSize();
> > > > >     final int loops = threads * 16;
> > > > >     final CountDownLatch latch = new CountDownLatch(loops);
> > > > >     final AtomicInteger counter = new AtomicInteger();
> > > > >     final CyclicBarrier barrier = new CyclicBarrier(threads +
> > > > 1);
> > > > >     for (int i = 0; i < loops; i++) {
> > > > >       THREAD_POOL_EXECUTOR.submit(new Runnable() {
> > > > >         public void run() {
> > > > >           if (counter.incrementAndGet() <= 
> barrier.getParties())
> > > > {
> > > > >             try {
> > > > >               barrier.await(1, TimeUnit.SECONDS);
> > > > >             } catch (Exception ign) {
> > > > >               // can be ignored (broken barrier is 
> tested below)
> > > > >             }
> > > > >           }
> > > > >           latch.countDown();
> > > > >         }
> > > > >       });
> > > > >     }
> > > > >     assertTrue( latch.await(2, TimeUnit.SECONDS));
> > > > >     assertFalse(barrier.isBroken());
> > > > >     assertEquals(0, barrier.getNumberWaiting());
> > > > >     assertEquals(loops, counter.get());
> > > > >   }
> > > > >
> > > > > }
> > > > >
> > > 
> > > 
> > 
> 
> 




More information about the Concurrency-interest mailing list