Calin Juravle | 8f0d92b | 2013-08-01 17:26:00 +0100 | [diff] [blame] | 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 | |
Narayan Kamath | 8e9a0e9 | 2015-04-28 11:40:00 +0100 | [diff] [blame] | 11 | import junit.framework.Test; |
| 12 | import junit.framework.TestSuite; |
Calin Juravle | 8f0d92b | 2013-08-01 17:26:00 +0100 | [diff] [blame] | 13 | |
| 14 | public class ThreadLocalTest extends JSR166TestCase { |
Narayan Kamath | 8e9a0e9 | 2015-04-28 11:40:00 +0100 | [diff] [blame] | 15 | // android-note: Removed because the CTS runner does a bad job of |
| 16 | // retrying tests that have suite() declarations. |
| 17 | // |
| 18 | // public static void main(String[] args) { |
| 19 | // main(suite(), args); |
| 20 | // } |
| 21 | // public static Test suite() { |
Przemyslaw Szczepaniak | b8b7511 | 2016-03-11 15:59:10 +0000 | [diff] [blame] | 22 | // return new TestSuite(ThreadLocalTest.class); |
Narayan Kamath | 8e9a0e9 | 2015-04-28 11:40:00 +0100 | [diff] [blame] | 23 | // } |
Calin Juravle | 8f0d92b | 2013-08-01 17:26:00 +0100 | [diff] [blame] | 24 | |
| 25 | static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() { |
| 26 | public Integer initialValue() { |
| 27 | return one; |
| 28 | } |
| 29 | }; |
| 30 | |
| 31 | static InheritableThreadLocal<Integer> itl = |
| 32 | new InheritableThreadLocal<Integer>() { |
| 33 | protected Integer initialValue() { |
| 34 | return zero; |
| 35 | } |
| 36 | |
| 37 | protected Integer childValue(Integer parentValue) { |
| 38 | return new Integer(parentValue.intValue() + 1); |
| 39 | } |
| 40 | }; |
| 41 | |
| 42 | /** |
| 43 | * remove causes next access to return initial value |
| 44 | */ |
| 45 | public void testRemove() { |
| 46 | assertSame(tl.get(), one); |
| 47 | tl.set(two); |
| 48 | assertSame(tl.get(), two); |
| 49 | tl.remove(); |
| 50 | assertSame(tl.get(), one); |
| 51 | } |
| 52 | |
| 53 | /** |
| 54 | * remove in InheritableThreadLocal causes next access to return |
| 55 | * initial value |
| 56 | */ |
| 57 | public void testRemoveITL() { |
| 58 | assertSame(itl.get(), zero); |
| 59 | itl.set(two); |
| 60 | assertSame(itl.get(), two); |
| 61 | itl.remove(); |
| 62 | assertSame(itl.get(), zero); |
| 63 | } |
| 64 | |
| 65 | private class ITLThread extends Thread { |
| 66 | final int[] x; |
| 67 | ITLThread(int[] array) { x = array; } |
| 68 | public void run() { |
| 69 | Thread child = null; |
| 70 | if (itl.get().intValue() < x.length - 1) { |
| 71 | child = new ITLThread(x); |
| 72 | child.start(); |
| 73 | } |
| 74 | Thread.yield(); |
| 75 | |
| 76 | int threadId = itl.get().intValue(); |
| 77 | for (int j = 0; j < threadId; j++) { |
| 78 | x[threadId]++; |
| 79 | Thread.yield(); |
| 80 | } |
| 81 | |
| 82 | if (child != null) { // Wait for child (if any) |
| 83 | try { |
| 84 | child.join(); |
| 85 | } catch (InterruptedException e) { |
| 86 | threadUnexpectedException(e); |
| 87 | } |
| 88 | } |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | /** |
| 93 | * InheritableThreadLocal propagates generic values. |
| 94 | */ |
| 95 | public void testGenericITL() throws InterruptedException { |
| 96 | final int threadCount = 10; |
Narayan Kamath | 8e9a0e9 | 2015-04-28 11:40:00 +0100 | [diff] [blame] | 97 | final int[] x = new int[threadCount]; |
Calin Juravle | 8f0d92b | 2013-08-01 17:26:00 +0100 | [diff] [blame] | 98 | Thread progenitor = new ITLThread(x); |
| 99 | progenitor.start(); |
| 100 | progenitor.join(); |
| 101 | for (int i = 0; i < threadCount; i++) { |
| 102 | assertEquals(i, x[i]); |
| 103 | } |
| 104 | } |
| 105 | } |