[concurrency-interest] ThreadPoolExecutorTestoccasionallyfailswith a broken barrier!?

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


The counter is compared to getParties to ensure that only the first 16
(pooled) + 1 (main) threads touch the barrier since the behaviour of
CyclicBarrier for additional threads arriving after the barrier was opened
(not broken) isn't obvious in the API doc. Actually the test will deadlock
if the counter isn't checked at all.

Oliver

> -----Original Message-----
> From: concurrency-interest-bounces at cs.oswego.edu 
> [mailto:concurrency-interest-bounces at cs.oswego.edu] On Behalf 
> Of David Holmes
> Sent: Wednesday, February 14, 2007 4:23 AM
> To: Joe Bowbeer; concurrency-interest at cs.oswego.edu
> Subject: RE: [concurrency-interest] 
> ThreadPoolExecutorTestoccasionallyfailswith a broken barrier!?
> 
> 
> 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