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      */
testRemove()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      */
testRemoveITL()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;
ITLThread(int[] array)58         ITLThread(int[] array) { x = array; }
run()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      */
testGenericITL()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