diff --git a/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactory.java b/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..00759c56cb62e9746bb2b63fc7745396cfdeab4d
--- /dev/null
+++ b/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactory.java
@@ -0,0 +1,18 @@
+package com.alibaba.ttl.threadpool;
+
+import javax.annotation.Nonnull;
+import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
+
+/**
+ * Disable inheritable {@link ForkJoinWorkerThreadFactory}.
+ *
+ * @author Jerry Lee (oldratlee at gmail dot com)
+ * @since 2.10.1
+ */
+public interface DisableInheritableForkJoinWorkerThreadFactory extends ForkJoinWorkerThreadFactory {
+ /**
+ * Unwrap {@link DisableInheritableThreadFactory} to the original/underneath one.
+ */
+ @Nonnull
+ ForkJoinWorkerThreadFactory unwrap();
+}
diff --git a/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactoryWrapper.java b/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactoryWrapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..c080d237231c8fc02eb2df3828243cc80291804f
--- /dev/null
+++ b/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableForkJoinWorkerThreadFactoryWrapper.java
@@ -0,0 +1,36 @@
+package com.alibaba.ttl.threadpool;
+
+import com.alibaba.ttl.TransmittableThreadLocal;
+
+import javax.annotation.Nonnull;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
+import java.util.concurrent.ForkJoinWorkerThread;
+
+/**
+ * @author Jerry Lee (oldratlee at gmail dot com)
+ * @since 2.10.1
+ */
+class DisableInheritableForkJoinWorkerThreadFactoryWrapper implements DisableInheritableForkJoinWorkerThreadFactory {
+ final ForkJoinWorkerThreadFactory threadFactory;
+
+ public DisableInheritableForkJoinWorkerThreadFactoryWrapper(@Nonnull ForkJoinWorkerThreadFactory threadFactory) {
+ this.threadFactory = threadFactory;
+ }
+
+ @Override
+ public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
+ final Object backup = TransmittableThreadLocal.Transmitter.clear();
+ try {
+ return threadFactory.newThread(pool);
+ } finally {
+ TransmittableThreadLocal.Transmitter.restore(backup);
+ }
+ }
+
+ @Nonnull
+ @Override
+ public ForkJoinWorkerThreadFactory unwrap() {
+ return threadFactory;
+ }
+}
diff --git a/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableThreadFactory.java b/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableThreadFactory.java
index edfb6646f522986292cb558febfb19df1662b6bd..091b64663b9e74dcf30b56d327420ef19cf7c2eb 100644
--- a/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableThreadFactory.java
+++ b/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableThreadFactory.java
@@ -4,11 +4,16 @@ import javax.annotation.Nonnull;
import java.util.concurrent.ThreadFactory;
/**
- * Disable inheritable thread factory.
+ * Disable inheritable {@link ThreadFactory}.
*
+ * @author Jerry Lee (oldratlee at gmail dot com)
* @see ThreadFactory
+ * @since 2.10.0
*/
public interface DisableInheritableThreadFactory extends ThreadFactory {
+ /**
+ * Unwrap {@link DisableInheritableThreadFactory} to the original/underneath one.
+ */
@Nonnull
ThreadFactory unwrap();
}
diff --git a/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableThreadFactoryWrapper.java b/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableThreadFactoryWrapper.java
index 8aba85fb9aad105cac2fe5d6ac6548b9b9c8d365..3b548257af28a14a1582ebf2f8dc3ae37a225b78 100644
--- a/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableThreadFactoryWrapper.java
+++ b/src/main/java/com/alibaba/ttl/threadpool/DisableInheritableThreadFactoryWrapper.java
@@ -5,6 +5,10 @@ import com.alibaba.ttl.TransmittableThreadLocal;
import javax.annotation.Nonnull;
import java.util.concurrent.ThreadFactory;
+/**
+ * @author Jerry Lee (oldratlee at gmail dot com)
+ * @since 2.10.0
+ */
class DisableInheritableThreadFactoryWrapper implements DisableInheritableThreadFactory {
final ThreadFactory threadFactory;
diff --git a/src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java b/src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java
index 502435c7a6bcfc45bb4b2ea2ee7a7b6b8b721e78..17cfaf260190a33fe76e4f88be2a3631de740203 100644
--- a/src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java
+++ b/src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java
@@ -25,6 +25,8 @@ import java.util.concurrent.*;
* @see java.util.concurrent.Executors
* @see java.util.concurrent.CompletionService
* @see java.util.concurrent.ExecutorCompletionService
+ * @see ThreadFactory
+ * @see Executors#defaultThreadFactory()
* @since 0.9.0
*/
public final class TtlExecutors {
diff --git a/src/main/java/com/alibaba/ttl/threadpool/TtlForkJoinPool.java b/src/main/java/com/alibaba/ttl/threadpool/TtlForkJoinPool.java
new file mode 100644
index 0000000000000000000000000000000000000000..36554871c86febdc0866125d6f28e8fa17ac410f
--- /dev/null
+++ b/src/main/java/com/alibaba/ttl/threadpool/TtlForkJoinPool.java
@@ -0,0 +1,70 @@
+package com.alibaba.ttl.threadpool;
+
+import javax.annotation.Nullable;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory;
+
+/**
+ * Factory Utils for getting TTL wrapper of {@link ForkJoinWorkerThreadFactory}.
+ *
+ * all method is {@code null}-safe, when input parameter(eg: {@link ForkJoinWorkerThreadFactory}) is {@code null}, return {@code null}.
+ *
+ * @author Jerry Lee (oldratlee at gmail dot com)
+ * @see ForkJoinPool
+ * @see ForkJoinWorkerThreadFactory
+ * @see ForkJoinPool#defaultForkJoinWorkerThreadFactory
+ * @since 2.10.1
+ */
+public class TtlForkJoinPool {
+ /**
+ * Wrapper of {@link ForkJoinWorkerThreadFactory}, disable inheritable.
+ *
+ * @param threadFactory input thread factory
+ * @see DisableInheritableForkJoinWorkerThreadFactory
+ * @since 2.10.1
+ */
+ @Nullable
+ public static ForkJoinWorkerThreadFactory getDisableInheritableForkJoinWorkerThreadFactory(@Nullable ForkJoinWorkerThreadFactory threadFactory) {
+ if (threadFactory == null || isDisableInheritableForkJoinWorkerThreadFactory(threadFactory))
+ return threadFactory;
+
+ return new DisableInheritableForkJoinWorkerThreadFactoryWrapper(threadFactory);
+ }
+
+ /**
+ * Wrapper of {@link ForkJoinPool#defaultForkJoinWorkerThreadFactory}, disable inheritable.
+ *
+ * @see #getDisableInheritableForkJoinWorkerThreadFactory(ForkJoinWorkerThreadFactory)
+ * @since 2.10.1
+ */
+ @Nullable
+ public static ForkJoinWorkerThreadFactory getDefaultDisableInheritableForkJoinWorkerThreadFactory() {
+ return getDisableInheritableForkJoinWorkerThreadFactory(ForkJoinPool.defaultForkJoinWorkerThreadFactory);
+ }
+
+ /**
+ * check the {@link ForkJoinWorkerThreadFactory} is {@link DisableInheritableForkJoinWorkerThreadFactory} or not.
+ *
+ * @see DisableInheritableForkJoinWorkerThreadFactory
+ * @since 2.10.1
+ */
+ public static boolean isDisableInheritableForkJoinWorkerThreadFactory(@Nullable ForkJoinWorkerThreadFactory threadFactory) {
+ return threadFactory instanceof DisableInheritableForkJoinWorkerThreadFactory;
+ }
+
+ /**
+ * Unwrap {@link DisableInheritableForkJoinWorkerThreadFactory} to the original/underneath one.
+ *
+ * @see DisableInheritableForkJoinWorkerThreadFactory
+ * @since 2.10.1
+ */
+ @Nullable
+ public static ForkJoinWorkerThreadFactory unwrap(@Nullable ForkJoinWorkerThreadFactory threadFactory) {
+ if (!isDisableInheritableForkJoinWorkerThreadFactory(threadFactory)) return threadFactory;
+
+ return ((DisableInheritableForkJoinWorkerThreadFactoryWrapper) threadFactory).unwrap();
+ }
+
+ private TtlForkJoinPool() {
+ }
+}
diff --git a/src/test/java/com/alibaba/support/junit/conditional/IsAgentRunOrBelowJava7.kt b/src/test/java/com/alibaba/support/junit/conditional/IsAgentRunOrBelowJava7.kt
new file mode 100644
index 0000000000000000000000000000000000000000..494a088efc1bcd9c420ef03a018c2d189316462b
--- /dev/null
+++ b/src/test/java/com/alibaba/support/junit/conditional/IsAgentRunOrBelowJava7.kt
@@ -0,0 +1,10 @@
+package com.alibaba.support.junit.conditional
+
+import com.alibaba.support.junit.conditional.ConditionalIgnoreRule.IgnoreCondition
+
+/**
+ * @see [Getting Java version at runtime](https://stackoverflow.com/a/23706899/922688)
+ */
+class IsAgentRunOrBelowJava7 : IgnoreCondition {
+ override fun isSatisfied(): Boolean = IsAgentRun().isSatisfied || BelowJava7().isSatisfied
+}
diff --git a/src/test/java/com/alibaba/ttl/InheritableTest.kt b/src/test/java/com/alibaba/ttl/InheritableTest.kt
index 4d13b24ed814b3a7eb6abd3defd243214c8cc1d3..8e24fd0152bab542d795bf024d9f7307e9a6e5c3 100644
--- a/src/test/java/com/alibaba/ttl/InheritableTest.kt
+++ b/src/test/java/com/alibaba/ttl/InheritableTest.kt
@@ -1,9 +1,12 @@
package com.alibaba.ttl
+import com.alibaba.support.junit.conditional.BelowJava7
import com.alibaba.support.junit.conditional.ConditionalIgnoreRule
import com.alibaba.support.junit.conditional.ConditionalIgnoreRule.ConditionalIgnore
import com.alibaba.support.junit.conditional.IsAgentRun
+import com.alibaba.support.junit.conditional.IsAgentRunOrBelowJava7
import com.alibaba.ttl.threadpool.TtlExecutors
+import com.alibaba.ttl.threadpool.TtlForkJoinPool
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Rule
@@ -11,6 +14,7 @@ import org.junit.Test
import java.util.*
import java.util.concurrent.Callable
import java.util.concurrent.Executors
+import java.util.concurrent.ForkJoinPool
private const val hello = "hello"
private val defaultValue = "${Date()} ${Math.random()}"
@@ -20,110 +24,245 @@ class InheritableTest {
@JvmField
val rule = ConditionalIgnoreRule()
+ // ===================================================
+ // Executors
+ // ===================================================
+
@Test
- fun inheritable() {
+ fun inheritable_Executors() {
val threadPool = Executors.newCachedThreadPool()
- val ttl = TransmittableThreadLocal()
- ttl.set(hello)
-
- val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+ try {
+ val ttl = TransmittableThreadLocal()
+ ttl.set(hello)
- // get "hello" value is transmitted by InheritableThreadLocal function!
- // NOTE: newCachedThreadPool create thread lazily
- assertEquals(hello, threadPool.submit(callable).get())
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
- // current thread's TTL must be exist when using DisableInheritableThreadFactory
- assertEquals(hello, ttl.get())
+ // get "hello" value is transmitted by InheritableThreadLocal function!
+ // NOTE: Executors.newCachedThreadPool create thread lazily
+ assertEquals(hello, threadPool.submit(callable).get())
- threadPool.shutdown()
+ // current thread's TTL must be exist
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
+ }
}
@Test
@ConditionalIgnore(condition = IsAgentRun::class)
- fun disableDisableInheritableThreadFactory() {
+ fun disableInheritable_Executors_DisableInheritableThreadFactory() {
val threadPool = Executors.newCachedThreadPool(TtlExecutors.getDefaultDisableInheritableThreadFactory())
- val ttl = TransmittableThreadLocal()
- ttl.set(hello)
+ try {
+ val ttl = TransmittableThreadLocal()
+ ttl.set(hello)
- val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+
+ // when ttl agent is loaded, Callable is wrapped when submit,
+ // so here value is "hello" transmitted by TtlCallable wrapper
+ // IGNORE this test case when TtlAgent is run.
+ assertNull(threadPool.submit(callable).get())
+
+ // current thread's TTL must be exist when using DisableInheritableThreadFactory
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
+ }
+ }
+
+ @Test
+ @ConditionalIgnore(condition = IsAgentRun::class)
+ fun disableInheritable_Executors_TtlDisableInheritableWithInitialValue() {
+ val threadPool = Executors.newCachedThreadPool()
+ try {
+ val ttl = object : TransmittableThreadLocal() {
+ override fun childValue(parentValue: String?): String? = initialValue()
+ }
+ ttl.set(hello)
- // when ttl agent is loaded, Callable is wrapped when submit,
- // so here value is "hello" transmitted by TtlCallable wrapper
- // IGNORE this test case when TtlAgent is run.
- assertNull(threadPool.submit(callable).get())
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
- // current thread's TTL must be exist when using DisableInheritableThreadFactory
- assertEquals(hello, ttl.get())
+ // when ttl agent is loaded, Callable is wrapped when submit,
+ // so here value is "hello" transmitted by TtlCallable wrapper
+ // IGNORE this test case when TtlAgent is run.
+ assertNull(threadPool.submit(callable).get())
- threadPool.shutdown()
+ // current thread's TTL must be exist
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
+ }
}
+ @Test
+ @ConditionalIgnore(condition = IsAgentRun::class)
+ fun disableInheritable_Executors_TtlDefaultValue_TtlDisableInheritableWithInitialValue() {
+ val threadPool = Executors.newCachedThreadPool()
+ try {
+ val ttl = object : TransmittableThreadLocal() {
+ override fun initialValue(): String = defaultValue
+ override fun childValue(parentValue: String): String = initialValue()
+ }
+ ttl.set(hello)
+
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+
+ // when ttl agent is loaded, Callable is wrapped when submit,
+ // so here value is "hello" transmitted by TtlCallable wrapper
+ // IGNORE this test case when TtlAgent is run.
+ assertEquals(defaultValue, threadPool.submit(callable).get())
+
+ // current thread's TTL must be exist when using DisableInheritableThreadFactory
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
+ }
+ }
@Test
@ConditionalIgnore(condition = IsAgentRun::class)
- fun disableDisableInheritableThreadFactory_TTL_with_initialValue() {
+ fun disableInheritable_Executors_TtlDefaultValue_DisableInheritableThreadFactory_TtlWithInitialValue() {
val threadPool = Executors.newCachedThreadPool(TtlExecutors.getDefaultDisableInheritableThreadFactory())
- val ttl = object : TransmittableThreadLocal() {
- override fun initialValue(): String = defaultValue
- override fun childValue(parentValue: String): String = initialValue()
+ try {
+ val ttl = object : TransmittableThreadLocal() {
+ override fun initialValue(): String = defaultValue
+ override fun childValue(parentValue: String): String = initialValue()
+ }
+ ttl.set(hello)
+
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+
+ // when ttl agent is loaded, Callable is wrapped when submit,
+ // so here value is "hello" transmitted by TtlCallable wrapper
+ // IGNORE this test case when TtlAgent is run.
+ assertEquals(defaultValue, threadPool.submit(callable).get())
+
+ // current thread's TTL must be exist when using DisableInheritableThreadFactory
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
}
- ttl.set(hello)
+ }
+
+ // ===================================================
+ // ForkJoinPool
+ // ===================================================
- val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+ @Test
+ @ConditionalIgnore(condition = BelowJava7::class)
+ fun inheritable_ForkJoinPool() {
+ val threadPool = ForkJoinPool(4)
+ try {
+ val ttl = TransmittableThreadLocal()
+ ttl.set(hello)
- // when ttl agent is loaded, Callable is wrapped when submit,
- // so here value is "hello" transmitted by TtlCallable wrapper
- // IGNORE this test case when TtlAgent is run.
- assertEquals(defaultValue, threadPool.submit(callable).get())
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
- // current thread's TTL must be exist when using DisableInheritableThreadFactory
- assertEquals(hello, ttl.get())
+ // get "hello" value is transmitted by InheritableThreadLocal function!
+ // NOTE: Executors.newCachedThreadPool create thread lazily
+ assertEquals(hello, threadPool.submit(callable).get())
- threadPool.shutdown()
+ // current thread's TTL must be exist
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
+ }
}
@Test
- @ConditionalIgnore(condition = IsAgentRun::class)
- fun disableInheritable() {
- val threadPool = Executors.newCachedThreadPool()
- val ttl = object : TransmittableThreadLocal() {
- override fun childValue(parentValue: String?): String? = initialValue()
+ @ConditionalIgnore(condition = IsAgentRunOrBelowJava7::class)
+ fun disableInheritable_ForkJoinPool_DisableInheritableForkJoinWorkerThreadFactory() {
+ val threadPool = ForkJoinPool(4, TtlForkJoinPool.getDefaultDisableInheritableForkJoinWorkerThreadFactory(), null, false)
+ try {
+ val ttl = TransmittableThreadLocal()
+ ttl.set(hello)
+
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+
+ // when ttl agent is loaded, Callable is wrapped when submit,
+ // so here value is "hello" transmitted by TtlCallable wrapper
+ // IGNORE this test case when TtlAgent is run.
+ assertNull(threadPool.submit(callable).get())
+
+ // current thread's TTL must be exist when using DisableInheritableForkJoinWorkerThreadFactory
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
}
- ttl.set(hello)
+ }
- val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+ @Test
+ @ConditionalIgnore(condition = IsAgentRunOrBelowJava7::class)
+ fun disableInheritable_ForkJoinPool_TtlDisableInheritableWithInitialValue() {
+ val threadPool = ForkJoinPool(4)
+ try {
+ val ttl = object : TransmittableThreadLocal() {
+ override fun childValue(parentValue: String?): String? = initialValue()
+ }
+ ttl.set(hello)
- // when ttl agent is loaded, Callable is wrapped when submit,
- // so here value is "hello" transmitted by TtlCallable wrapper
- // IGNORE this test case when TtlAgent is run.
- assertNull(threadPool.submit(callable).get())
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
- // current thread's TTL must be exist when using DisableInheritableThreadFactory
- assertEquals(hello, ttl.get())
+ // when ttl agent is loaded, Callable is wrapped when submit,
+ // so here value is "hello" transmitted by TtlCallable wrapper
+ // IGNORE this test case when TtlAgent is run.
+ assertNull(threadPool.submit(callable).get())
- threadPool.shutdown()
+ // current thread's TTL must be exist
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
+ }
}
@Test
- @ConditionalIgnore(condition = IsAgentRun::class)
- fun disableInheritable_TTL_with_initialValue() {
- val threadPool = Executors.newCachedThreadPool()
- val ttl = object : TransmittableThreadLocal() {
- override fun initialValue(): String = defaultValue
- override fun childValue(parentValue: String): String = initialValue()
+ @ConditionalIgnore(condition = IsAgentRunOrBelowJava7::class)
+ fun disableInheritable_ForkJoinPool_TtlDefaultValue_TtlDisableInheritableWithInitialValue() {
+ val threadPool = ForkJoinPool(4)
+ try {
+ val ttl = object : TransmittableThreadLocal() {
+ override fun initialValue(): String = defaultValue
+ override fun childValue(parentValue: String): String = initialValue()
+ }
+ ttl.set(hello)
+
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+
+ // when ttl agent is loaded, Callable is wrapped when submit,
+ // so here value is "hello" transmitted by TtlCallable wrapper
+ // IGNORE this test case when TtlAgent is run.
+ assertEquals(defaultValue, threadPool.submit(callable).get())
+
+ // current thread's TTL must be exist
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
}
- ttl.set(hello)
+ }
- val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
+ @Test
+ @ConditionalIgnore(condition = IsAgentRunOrBelowJava7::class)
+ fun disableInheritable_ForkJoinPool_TtlDefaultValue_DisableInheritableForkJoinWorkerThreadFactory_TtlWithInitialValue() {
+ val threadPool = ForkJoinPool(4, TtlForkJoinPool.getDefaultDisableInheritableForkJoinWorkerThreadFactory(), null, false)
+ try {
+ val ttl = object : TransmittableThreadLocal() {
+ override fun initialValue(): String = defaultValue
+ override fun childValue(parentValue: String): String = initialValue()
+ }
+ ttl.set(hello)
- // when ttl agent is loaded, Callable is wrapped when submit,
- // so here value is "hello" transmitted by TtlCallable wrapper
- // IGNORE this test case when TtlAgent is run.
- assertEquals(defaultValue, threadPool.submit(callable).get())
+ val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
- // current thread's TTL must be exist when using DisableInheritableThreadFactory
- assertEquals(hello, ttl.get())
+ // when ttl agent is loaded, Callable is wrapped when submit,
+ // so here value is "hello" transmitted by TtlCallable wrapper
+ // IGNORE this test case when TtlAgent is run.
+ assertEquals(defaultValue, threadPool.submit(callable).get())
- threadPool.shutdown()
+ // current thread's TTL must be exist when using DisableInheritableForkJoinWorkerThreadFactory
+ assertEquals(hello, ttl.get())
+ } finally {
+ threadPool.shutdown()
+ }
}
+
}
diff --git a/src/test/java/com/alibaba/ttl/threadpool/TtlExecutorsTest.kt b/src/test/java/com/alibaba/ttl/threadpool/TtlExecutorsTest.kt
index 543b967976947d515f811527361768d0a1bfbb6b..44c61bfaa86e6a26ffb27cacf8c3935ea3f3852e 100644
--- a/src/test/java/com/alibaba/ttl/threadpool/TtlExecutorsTest.kt
+++ b/src/test/java/com/alibaba/ttl/threadpool/TtlExecutorsTest.kt
@@ -1,54 +1,59 @@
package com.alibaba.ttl.threadpool
-import com.alibaba.support.junit.conditional.ConditionalIgnoreRule
-import com.alibaba.support.junit.conditional.ConditionalIgnoreRule.ConditionalIgnore
-import com.alibaba.support.junit.conditional.IsAgentRun
+import com.alibaba.noTtlAgentRun
import com.alibaba.ttl.threadpool.TtlExecutors.*
import org.junit.Assert.*
-import org.junit.Rule
import org.junit.Test
+import java.util.concurrent.Executor
import java.util.concurrent.Executors.newScheduledThreadPool
+import java.util.concurrent.ThreadFactory
/**
* @author Jerry Lee (oldratlee at gmail dot com)
*/
class TtlExecutorsTest {
- @Rule
- @JvmField
- val rule = ConditionalIgnoreRule()
@Test
- @ConditionalIgnore(condition = IsAgentRun::class)
- fun test_common() {
+ fun test_common_executors() {
val newScheduledThreadPool = newScheduledThreadPool(3)
getTtlExecutor(newScheduledThreadPool).let {
- assertTrue(it is ExecutorTtlWrapper)
- assertTrue(isTtlWrapper(it))
+ if (noTtlAgentRun()) assertTrue(it is ExecutorTtlWrapper)
+ assertEquals(noTtlAgentRun(), isTtlWrapper(it))
assertSame(newScheduledThreadPool, unwrap(it))
}
getTtlExecutorService(newScheduledThreadPool).let {
- assertTrue(it is ExecutorServiceTtlWrapper)
- assertTrue(isTtlWrapper(it))
+ if (noTtlAgentRun()) assertTrue(it is ExecutorServiceTtlWrapper)
+ assertEquals(noTtlAgentRun(), isTtlWrapper(it))
assertSame(newScheduledThreadPool, unwrap(it))
}
getTtlScheduledExecutorService(newScheduledThreadPool).let {
- assertTrue(it is ScheduledExecutorServiceTtlWrapper)
- assertTrue(isTtlWrapper(it))
+ if (noTtlAgentRun()) assertTrue(it is ScheduledExecutorServiceTtlWrapper)
+ assertEquals(noTtlAgentRun(), isTtlWrapper(it))
assertSame(newScheduledThreadPool, unwrap(it))
}
+
+ val threadFactory = ThreadFactory { Thread(it) }
+ getDisableInheritableThreadFactory(threadFactory).let {
+ assertTrue(it is DisableInheritableThreadFactory)
+ assertTrue(isDisableInheritableThreadFactory(it))
+
+ assertSame(threadFactory, unwrap(it))
+ }
}
@Test
- fun test_null() {
+ fun test_null_executors() {
assertNull(getTtlExecutor(null))
assertNull(getTtlExecutorService(null))
assertNull(getTtlScheduledExecutorService(null))
assertFalse(isTtlWrapper(null))
- assertNull(unwrap(null))
+ assertNull(unwrap(null))
}
+
+
}
diff --git a/src/test/java/com/alibaba/ttl/threadpool/TtlForkJoinPoolTest.kt b/src/test/java/com/alibaba/ttl/threadpool/TtlForkJoinPoolTest.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6e5acbd8072ba876768d3f5b8cca4be4ec484859
--- /dev/null
+++ b/src/test/java/com/alibaba/ttl/threadpool/TtlForkJoinPoolTest.kt
@@ -0,0 +1,32 @@
+package com.alibaba.ttl.threadpool
+
+import com.alibaba.support.junit.conditional.BelowJava7
+import com.alibaba.support.junit.conditional.ConditionalIgnoreRule
+import org.junit.Assert.*
+import org.junit.Rule
+import org.junit.Test
+import java.util.concurrent.ForkJoinPool
+
+class TtlForkJoinPoolTest {
+ @Rule
+ @JvmField
+ val rule = ConditionalIgnoreRule()
+
+ @Test
+ @ConditionalIgnoreRule.ConditionalIgnore(condition = BelowJava7::class)
+ fun test_common_ForkJoinPool() {
+ TtlForkJoinPool.getDefaultDisableInheritableForkJoinWorkerThreadFactory().let {
+ assertTrue(it is DisableInheritableForkJoinWorkerThreadFactory)
+ assertTrue(TtlForkJoinPool.isDisableInheritableForkJoinWorkerThreadFactory(it))
+
+ assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory, TtlForkJoinPool.unwrap(it))
+ }
+ }
+
+ @Test
+ @ConditionalIgnoreRule.ConditionalIgnore(condition = BelowJava7::class)
+ fun test_null_ForkJoinPool() {
+ assertFalse(TtlForkJoinPool.isDisableInheritableForkJoinWorkerThreadFactory(null))
+ assertNull(TtlForkJoinPool.unwrap(null as? ForkJoinPool.ForkJoinWorkerThreadFactory))
+ }
+}