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.concurrent.Semaphore;
     13 
     14 public class ThreadLocalTest extends JSR166TestCase {
     15 
     16     static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
     17             public Integer initialValue() {
     18                 return one;
     19             }
     20         };
     21 
     22     static InheritableThreadLocal<Integer> itl =
     23         new InheritableThreadLocal<Integer>() {
     24             protected Integer initialValue() {
     25                 return zero;
     26             }
     27 
     28             protected Integer childValue(Integer parentValue) {
     29                 return new Integer(parentValue.intValue() + 1);
     30             }
     31         };
     32 
     33     /**
     34      * remove causes next access to return initial value
     35      */
     36     public void testRemove() {
     37         assertSame(tl.get(), one);
     38         tl.set(two);
     39         assertSame(tl.get(), two);
     40         tl.remove();
     41         assertSame(tl.get(), one);
     42     }
     43 
     44     /**
     45      * remove in InheritableThreadLocal causes next access to return
     46      * initial value
     47      */
     48     public void testRemoveITL() {
     49         assertSame(itl.get(), zero);
     50         itl.set(two);
     51         assertSame(itl.get(), two);
     52         itl.remove();
     53         assertSame(itl.get(), zero);
     54     }
     55 
     56     private class ITLThread extends Thread {
     57         final int[] x;
     58         ITLThread(int[] array) { x = array; }
     59         public void run() {
     60             Thread child = null;
     61             if (itl.get().intValue() < x.length - 1) {
     62                 child = new ITLThread(x);
     63                 child.start();
     64             }
     65             Thread.yield();
     66 
     67             int threadId = itl.get().intValue();
     68             for (int j = 0; j < threadId; j++) {
     69                 x[threadId]++;
     70                 Thread.yield();
     71             }
     72 
     73             if (child != null) { // Wait for child (if any)
     74                 try {
     75                     child.join();
     76                 } catch (InterruptedException e) {
     77                     threadUnexpectedException(e);
     78                 }
     79             }
     80         }
     81     }
     82 
     83     /**
     84      * InheritableThreadLocal propagates generic values.
     85      */
     86     public void testGenericITL() throws InterruptedException {
     87         final int threadCount = 10;
     88         final int x[] = new int[threadCount];
     89         Thread progenitor = new ITLThread(x);
     90         progenitor.start();
     91         progenitor.join();
     92         for (int i = 0; i < threadCount; i++) {
     93             assertEquals(i, x[i]);
     94         }
     95     }
     96 }
     97