1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea with assistance from members of JCP JSR-166 30 * Expert Group and released to the public domain, as explained at 31 * http://creativecommons.org/publicdomain/zero/1.0/ 32 * Other contributors include Andrew Wright, Jeffrey Hayes, 33 * Pat Fisher, Mike Judd. 34 */ 35 36 import junit.framework.Test; 37 import junit.framework.TestSuite; 38 39 public class ThreadLocalTest extends JSR166TestCase { main(String[] args)40 public static void main(String[] args) { 41 main(suite(), args); 42 } 43 suite()44 public static Test suite() { 45 return new TestSuite(ThreadLocalTest.class); 46 } 47 48 static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() { 49 public Integer initialValue() { 50 return one; 51 } 52 }; 53 54 static InheritableThreadLocal<Integer> itl = 55 new InheritableThreadLocal<Integer>() { 56 protected Integer initialValue() { 57 return zero; 58 } 59 60 protected Integer childValue(Integer parentValue) { 61 return new Integer(parentValue.intValue() + 1); 62 } 63 }; 64 65 /** 66 * remove causes next access to return initial value 67 */ testRemove()68 public void testRemove() { 69 assertSame(tl.get(), one); 70 tl.set(two); 71 assertSame(tl.get(), two); 72 tl.remove(); 73 assertSame(tl.get(), one); 74 } 75 76 /** 77 * remove in InheritableThreadLocal causes next access to return 78 * initial value 79 */ testRemoveITL()80 public void testRemoveITL() { 81 assertSame(itl.get(), zero); 82 itl.set(two); 83 assertSame(itl.get(), two); 84 itl.remove(); 85 assertSame(itl.get(), zero); 86 } 87 88 private class ITLThread extends Thread { 89 final int[] x; ITLThread(int[] array)90 ITLThread(int[] array) { x = array; } run()91 public void run() { 92 Thread child = null; 93 if (itl.get().intValue() < x.length - 1) { 94 child = new ITLThread(x); 95 child.start(); 96 } 97 Thread.yield(); 98 99 int threadId = itl.get().intValue(); 100 for (int j = 0; j < threadId; j++) { 101 x[threadId]++; 102 Thread.yield(); 103 } 104 105 if (child != null) { // Wait for child (if any) 106 try { 107 child.join(); 108 } catch (InterruptedException e) { 109 threadUnexpectedException(e); 110 } 111 } 112 } 113 } 114 115 /** 116 * InheritableThreadLocal propagates generic values. 117 */ testGenericITL()118 public void testGenericITL() throws InterruptedException { 119 final int threadCount = 10; 120 final int[] x = new int[threadCount]; 121 Thread progenitor = new ITLThread(x); 122 progenitor.start(); 123 progenitor.join(); 124 for (int i = 0; i < threadCount; i++) { 125 assertEquals(i, x[i]); 126 } 127 } 128 } 129