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 junit.framework.*;
     12 import java.util.*;
     13 import java.util.concurrent.CountDownLatch;
     14 import java.util.concurrent.Exchanger;
     15 import java.util.concurrent.TimeoutException;
     16 import static java.util.concurrent.TimeUnit.MILLISECONDS;
     17 
     18 public class ExchangerTest extends JSR166TestCase {
     19 
     20     /**
     21      * exchange exchanges objects across two threads
     22      */
     23     public void testExchange() {
     24         final Exchanger e = new Exchanger();
     25         Thread t1 = newStartedThread(new CheckedRunnable() {
     26             public void realRun() throws InterruptedException {
     27                 assertSame(one, e.exchange(two));
     28                 assertSame(two, e.exchange(one));
     29             }});
     30         Thread t2 = newStartedThread(new CheckedRunnable() {
     31             public void realRun() throws InterruptedException {
     32                 assertSame(two, e.exchange(one));
     33                 assertSame(one, e.exchange(two));
     34             }});
     35 
     36         awaitTermination(t1);
     37         awaitTermination(t2);
     38     }
     39 
     40     /**
     41      * timed exchange exchanges objects across two threads
     42      */
     43     public void testTimedExchange() {
     44         final Exchanger e = new Exchanger();
     45         Thread t1 = newStartedThread(new CheckedRunnable() {
     46             public void realRun() throws Exception {
     47                 assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
     48                 assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
     49             }});
     50         Thread t2 = newStartedThread(new CheckedRunnable() {
     51             public void realRun() throws Exception {
     52                 assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
     53                 assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
     54             }});
     55 
     56         awaitTermination(t1);
     57         awaitTermination(t2);
     58     }
     59 
     60     /**
     61      * interrupt during wait for exchange throws IE
     62      */
     63     public void testExchange_InterruptedException() {
     64         final Exchanger e = new Exchanger();
     65         final CountDownLatch threadStarted = new CountDownLatch(1);
     66         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
     67             public void realRun() throws InterruptedException {
     68                 threadStarted.countDown();
     69                 e.exchange(one);
     70             }});
     71 
     72         await(threadStarted);
     73         t.interrupt();
     74         awaitTermination(t);
     75     }
     76 
     77     /**
     78      * interrupt during wait for timed exchange throws IE
     79      */
     80     public void testTimedExchange_InterruptedException() {
     81         final Exchanger e = new Exchanger();
     82         final CountDownLatch threadStarted = new CountDownLatch(1);
     83         Thread t = newStartedThread(new CheckedInterruptedRunnable() {
     84             public void realRun() throws Exception {
     85                 threadStarted.countDown();
     86                 e.exchange(null, LONG_DELAY_MS, MILLISECONDS);
     87             }});
     88 
     89         await(threadStarted);
     90         t.interrupt();
     91         awaitTermination(t);
     92     }
     93 
     94     /**
     95      * timeout during wait for timed exchange throws TimeoutException
     96      */
     97     public void testExchange_TimeoutException() {
     98         final Exchanger e = new Exchanger();
     99         Thread t = newStartedThread(new CheckedRunnable() {
    100             public void realRun() throws Exception {
    101                 long startTime = System.nanoTime();
    102                 try {
    103                     e.exchange(null, timeoutMillis(), MILLISECONDS);
    104                     shouldThrow();
    105                 } catch (TimeoutException success) {}
    106                 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
    107             }});
    108 
    109         awaitTermination(t);
    110     }
    111 
    112     /**
    113      * If one exchanging thread is interrupted, another succeeds.
    114      */
    115     public void testReplacementAfterExchange() {
    116         final Exchanger e = new Exchanger();
    117         final CountDownLatch exchanged = new CountDownLatch(2);
    118         final CountDownLatch interrupted = new CountDownLatch(1);
    119         Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
    120             public void realRun() throws InterruptedException {
    121                 assertSame(two, e.exchange(one));
    122                 exchanged.countDown();
    123                 e.exchange(two);
    124             }});
    125         Thread t2 = newStartedThread(new CheckedRunnable() {
    126             public void realRun() throws InterruptedException {
    127                 assertSame(one, e.exchange(two));
    128                 exchanged.countDown();
    129                 interrupted.await();
    130                 assertSame(three, e.exchange(one));
    131             }});
    132         Thread t3 = newStartedThread(new CheckedRunnable() {
    133             public void realRun() throws InterruptedException {
    134                 interrupted.await();
    135                 assertSame(one, e.exchange(three));
    136             }});
    137 
    138         await(exchanged);
    139         t1.interrupt();
    140         awaitTermination(t1);
    141         interrupted.countDown();
    142         awaitTermination(t2);
    143         awaitTermination(t3);
    144     }
    145 
    146 }
    147