Home | History | Annotate | Download | only in jsr166
      1 /*
      2  * Written by Doug Lea with assistance from members of JCP JSR-166
      3  * Expert Group and released to the public domain, as explained at
      4  * http://creativecommons.org/publicdomain/zero/1.0/
      5  * Other contributors include Andrew Wright, Jeffrey Hayes,
      6  * Pat Fisher, Mike Judd.
      7  */
      8 
      9 package jsr166;
     10 
     11 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     12 
     13 import java.util.concurrent.CountDownLatch;
     14 import java.util.concurrent.Exchanger;
     15 import java.util.concurrent.TimeoutException;
     16 
     17 import junit.framework.Test;
     18 import junit.framework.TestSuite;
     19 
     20 public class ExchangerTest extends JSR166TestCase {
     21 
     22     // android-note: Removed because the CTS runner does a bad job of
     23     // retrying tests that have suite() declarations.
     24     //
     25     // public static void main(String[] args) {
     26     //     main(suite(), args);
     27     // }
     28     // public static Test suite() {
     29     //     return new TestSuite(...);
     30     // }
     31 
     32     /**
     33      * exchange exchanges objects across two threads
     34      */
     35     public void testExchange() {
     36         final Exchanger e = new Exchanger();
     37         Thread t1 = newStartedThread(new CheckedRunnable() {
     38             public void realRun() throws InterruptedException {
     39                 assertSame(one, e.exchange(two));
     40                 assertSame(two, e.exchange(one));
     41             }});
     42         Thread t2 = newStartedThread(new CheckedRunnable() {
     43             public void realRun() throws InterruptedException {
     44                 assertSame(two, e.exchange(one));
     45                 assertSame(one, e.exchange(two));
     46             }});
     47 
     48         awaitTermination(t1);
     49         awaitTermination(t2);
     50     }
     51 
     52     /**
     53      * timed exchange exchanges objects across two threads
     54      */
     55     public void testTimedExchange() {
     56         final Exchanger e = new Exchanger();
     57         Thread t1 = newStartedThread(new CheckedRunnable() {
     58             public void realRun() throws Exception {
     59                 assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
     60                 assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
     61             }});
     62         Thread t2 = newStartedThread(new CheckedRunnable() {
     63             public void realRun() throws Exception {
     64                 assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
     65                 assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
     66             }});
     67 
     68         awaitTermination(t1);
     69         awaitTermination(t2);
     70     }
     71 
     72     /**
     73      * interrupt during wait for exchange throws IE
     74      */
     75     public void testExchange_InterruptedException() {
     76         final Exchanger e = new Exchanger();
     77         final CountDownLatch threadStarted = new CountDownLatch(1);
     78         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
     79             public void realRun() throws InterruptedException {
     80                 threadStarted.countDown();
     81                 e.exchange(one);
     82             }});
     83 
     84         await(threadStarted);
     85         t.interrupt();
     86         awaitTermination(t);
     87     }
     88 
     89     /**
     90      * interrupt during wait for timed exchange throws IE
     91      */
     92     public void testTimedExchange_InterruptedException() {
     93         final Exchanger e = new Exchanger();
     94         final CountDownLatch threadStarted = new CountDownLatch(1);
     95         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
     96             public void realRun() throws Exception {
     97                 threadStarted.countDown();
     98                 e.exchange(null, LONG_DELAY_MS, MILLISECONDS);
     99             }});
    100 
    101         await(threadStarted);
    102         t.interrupt();
    103         awaitTermination(t);
    104     }
    105 
    106     /**
    107      * timeout during wait for timed exchange throws TimeoutException
    108      */
    109     public void testExchange_TimeoutException() {
    110         final Exchanger e = new Exchanger();
    111         Thread t = newStartedThread(new CheckedRunnable() {
    112             public void realRun() throws Exception {
    113                 long startTime = System.nanoTime();
    114                 try {
    115                     e.exchange(null, timeoutMillis(), MILLISECONDS);
    116                     shouldThrow();
    117                 } catch (TimeoutException success) {}
    118                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    119             }});
    120 
    121         awaitTermination(t);
    122     }
    123 
    124     /**
    125      * If one exchanging thread is interrupted, another succeeds.
    126      */
    127     public void testReplacementAfterExchange() {
    128         final Exchanger e = new Exchanger();
    129         final CountDownLatch exchanged = new CountDownLatch(2);
    130         final CountDownLatch interrupted = new CountDownLatch(1);
    131         Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
    132             public void realRun() throws InterruptedException {
    133                 assertSame(two, e.exchange(one));
    134                 exchanged.countDown();
    135                 e.exchange(two);
    136             }});
    137         Thread t2 = newStartedThread(new CheckedRunnable() {
    138             public void realRun() throws InterruptedException {
    139                 assertSame(one, e.exchange(two));
    140                 exchanged.countDown();
    141                 interrupted.await();
    142                 assertSame(three, e.exchange(one));
    143             }});
    144         Thread t3 = newStartedThread(new CheckedRunnable() {
    145             public void realRun() throws InterruptedException {
    146                 interrupted.await();
    147                 assertSame(one, e.exchange(three));
    148             }});
    149 
    150         await(exchanged);
    151         t1.interrupt();
    152         awaitTermination(t1);
    153         interrupted.countDown();
    154         awaitTermination(t2);
    155         awaitTermination(t3);
    156     }
    157 
    158 }
    159