提交 9450809a 编写于 作者: oldratlee's avatar oldratlee 🔥

add DisableInheritableForkJoinWorkerThreadFactory and unit test

上级 ef6fec36
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();
}
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;
}
}
...@@ -4,11 +4,16 @@ import javax.annotation.Nonnull; ...@@ -4,11 +4,16 @@ import javax.annotation.Nonnull;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
/** /**
* Disable inheritable thread factory. * Disable inheritable {@link ThreadFactory}.
* *
* @author Jerry Lee (oldratlee at gmail dot com)
* @see ThreadFactory * @see ThreadFactory
* @since 2.10.0
*/ */
public interface DisableInheritableThreadFactory extends ThreadFactory { public interface DisableInheritableThreadFactory extends ThreadFactory {
/**
* Unwrap {@link DisableInheritableThreadFactory} to the original/underneath one.
*/
@Nonnull @Nonnull
ThreadFactory unwrap(); ThreadFactory unwrap();
} }
...@@ -5,6 +5,10 @@ import com.alibaba.ttl.TransmittableThreadLocal; ...@@ -5,6 +5,10 @@ import com.alibaba.ttl.TransmittableThreadLocal;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
/**
* @author Jerry Lee (oldratlee at gmail dot com)
* @since 2.10.0
*/
class DisableInheritableThreadFactoryWrapper implements DisableInheritableThreadFactory { class DisableInheritableThreadFactoryWrapper implements DisableInheritableThreadFactory {
final ThreadFactory threadFactory; final ThreadFactory threadFactory;
......
...@@ -25,6 +25,8 @@ import java.util.concurrent.*; ...@@ -25,6 +25,8 @@ import java.util.concurrent.*;
* @see java.util.concurrent.Executors * @see java.util.concurrent.Executors
* @see java.util.concurrent.CompletionService * @see java.util.concurrent.CompletionService
* @see java.util.concurrent.ExecutorCompletionService * @see java.util.concurrent.ExecutorCompletionService
* @see ThreadFactory
* @see Executors#defaultThreadFactory()
* @since 0.9.0 * @since 0.9.0
*/ */
public final class TtlExecutors { public final class TtlExecutors {
......
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}.
* <p>
* 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() {
}
}
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
}
package com.alibaba.ttl 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
import com.alibaba.support.junit.conditional.ConditionalIgnoreRule.ConditionalIgnore import com.alibaba.support.junit.conditional.ConditionalIgnoreRule.ConditionalIgnore
import com.alibaba.support.junit.conditional.IsAgentRun 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.TtlExecutors
import com.alibaba.ttl.threadpool.TtlForkJoinPool
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull import org.junit.Assert.assertNull
import org.junit.Rule import org.junit.Rule
...@@ -11,6 +14,7 @@ import org.junit.Test ...@@ -11,6 +14,7 @@ import org.junit.Test
import java.util.* import java.util.*
import java.util.concurrent.Callable import java.util.concurrent.Callable
import java.util.concurrent.Executors import java.util.concurrent.Executors
import java.util.concurrent.ForkJoinPool
private const val hello = "hello" private const val hello = "hello"
private val defaultValue = "${Date()} ${Math.random()}" private val defaultValue = "${Date()} ${Math.random()}"
...@@ -20,110 +24,245 @@ class InheritableTest { ...@@ -20,110 +24,245 @@ class InheritableTest {
@JvmField @JvmField
val rule = ConditionalIgnoreRule() val rule = ConditionalIgnoreRule()
// ===================================================
// Executors
// ===================================================
@Test @Test
fun inheritable() { fun inheritable_Executors() {
val threadPool = Executors.newCachedThreadPool() val threadPool = Executors.newCachedThreadPool()
val ttl = TransmittableThreadLocal<String?>() try {
ttl.set(hello) val ttl = TransmittableThreadLocal<String?>()
ttl.set(hello)
val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
// get "hello" value is transmitted by InheritableThreadLocal function! val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
// NOTE: newCachedThreadPool create thread lazily
assertEquals(hello, threadPool.submit(callable).get())
// current thread's TTL must be exist when using DisableInheritableThreadFactory // get "hello" value is transmitted by InheritableThreadLocal function!
assertEquals(hello, ttl.get()) // 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 @Test
@ConditionalIgnore(condition = IsAgentRun::class) @ConditionalIgnore(condition = IsAgentRun::class)
fun disableDisableInheritableThreadFactory() { fun disableInheritable_Executors_DisableInheritableThreadFactory() {
val threadPool = Executors.newCachedThreadPool(TtlExecutors.getDefaultDisableInheritableThreadFactory()) val threadPool = Executors.newCachedThreadPool(TtlExecutors.getDefaultDisableInheritableThreadFactory())
val ttl = TransmittableThreadLocal<String?>() try {
ttl.set(hello) val ttl = TransmittableThreadLocal<String?>()
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<String?>() {
override fun childValue(parentValue: String?): String? = initialValue()
}
ttl.set(hello)
// when ttl agent is loaded, Callable is wrapped when submit, val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
// 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 // when ttl agent is loaded, Callable is wrapped when submit,
assertEquals(hello, ttl.get()) // 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<String>() {
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 @Test
@ConditionalIgnore(condition = IsAgentRun::class) @ConditionalIgnore(condition = IsAgentRun::class)
fun disableDisableInheritableThreadFactory_TTL_with_initialValue() { fun disableInheritable_Executors_TtlDefaultValue_DisableInheritableThreadFactory_TtlWithInitialValue() {
val threadPool = Executors.newCachedThreadPool(TtlExecutors.getDefaultDisableInheritableThreadFactory()) val threadPool = Executors.newCachedThreadPool(TtlExecutors.getDefaultDisableInheritableThreadFactory())
val ttl = object : TransmittableThreadLocal<String>() { try {
override fun initialValue(): String = defaultValue val ttl = object : TransmittableThreadLocal<String>() {
override fun childValue(parentValue: String): String = initialValue() 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<String?>()
ttl.set(hello)
// when ttl agent is loaded, Callable is wrapped when submit, val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
// 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 // get "hello" value is transmitted by InheritableThreadLocal function!
assertEquals(hello, ttl.get()) // 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 @Test
@ConditionalIgnore(condition = IsAgentRun::class) @ConditionalIgnore(condition = IsAgentRunOrBelowJava7::class)
fun disableInheritable() { fun disableInheritable_ForkJoinPool_DisableInheritableForkJoinWorkerThreadFactory() {
val threadPool = Executors.newCachedThreadPool() val threadPool = ForkJoinPool(4, TtlForkJoinPool.getDefaultDisableInheritableForkJoinWorkerThreadFactory(), null, false)
val ttl = object : TransmittableThreadLocal<String?>() { try {
override fun childValue(parentValue: String?): String? = initialValue() val ttl = TransmittableThreadLocal<String?>()
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<String?>() {
override fun childValue(parentValue: String?): String? = initialValue()
}
ttl.set(hello)
// when ttl agent is loaded, Callable is wrapped when submit, val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
// 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 // when ttl agent is loaded, Callable is wrapped when submit,
assertEquals(hello, ttl.get()) // 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 @Test
@ConditionalIgnore(condition = IsAgentRun::class) @ConditionalIgnore(condition = IsAgentRunOrBelowJava7::class)
fun disableInheritable_TTL_with_initialValue() { fun disableInheritable_ForkJoinPool_TtlDefaultValue_TtlDisableInheritableWithInitialValue() {
val threadPool = Executors.newCachedThreadPool() val threadPool = ForkJoinPool(4)
val ttl = object : TransmittableThreadLocal<String>() { try {
override fun initialValue(): String = defaultValue val ttl = object : TransmittableThreadLocal<String>() {
override fun childValue(parentValue: String): String = initialValue() 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<String>() {
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, val callable = Callable { ttl.get() } // NO TtlWrapper(TtlCallable) here!!
// 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 // when ttl agent is loaded, Callable is wrapped when submit,
assertEquals(hello, ttl.get()) // 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()
}
} }
} }
package com.alibaba.ttl.threadpool package com.alibaba.ttl.threadpool
import com.alibaba.support.junit.conditional.ConditionalIgnoreRule import com.alibaba.noTtlAgentRun
import com.alibaba.support.junit.conditional.ConditionalIgnoreRule.ConditionalIgnore
import com.alibaba.support.junit.conditional.IsAgentRun
import com.alibaba.ttl.threadpool.TtlExecutors.* import com.alibaba.ttl.threadpool.TtlExecutors.*
import org.junit.Assert.* import org.junit.Assert.*
import org.junit.Rule
import org.junit.Test import org.junit.Test
import java.util.concurrent.Executor
import java.util.concurrent.Executors.newScheduledThreadPool import java.util.concurrent.Executors.newScheduledThreadPool
import java.util.concurrent.ThreadFactory
/** /**
* @author Jerry Lee (oldratlee at gmail dot com) * @author Jerry Lee (oldratlee at gmail dot com)
*/ */
class TtlExecutorsTest { class TtlExecutorsTest {
@Rule
@JvmField
val rule = ConditionalIgnoreRule()
@Test @Test
@ConditionalIgnore(condition = IsAgentRun::class) fun test_common_executors() {
fun test_common() {
val newScheduledThreadPool = newScheduledThreadPool(3) val newScheduledThreadPool = newScheduledThreadPool(3)
getTtlExecutor(newScheduledThreadPool).let { getTtlExecutor(newScheduledThreadPool).let {
assertTrue(it is ExecutorTtlWrapper) if (noTtlAgentRun()) assertTrue(it is ExecutorTtlWrapper)
assertTrue(isTtlWrapper(it)) assertEquals(noTtlAgentRun(), isTtlWrapper(it))
assertSame(newScheduledThreadPool, unwrap(it)) assertSame(newScheduledThreadPool, unwrap(it))
} }
getTtlExecutorService(newScheduledThreadPool).let { getTtlExecutorService(newScheduledThreadPool).let {
assertTrue(it is ExecutorServiceTtlWrapper) if (noTtlAgentRun()) assertTrue(it is ExecutorServiceTtlWrapper)
assertTrue(isTtlWrapper(it)) assertEquals(noTtlAgentRun(), isTtlWrapper(it))
assertSame(newScheduledThreadPool, unwrap(it)) assertSame(newScheduledThreadPool, unwrap(it))
} }
getTtlScheduledExecutorService(newScheduledThreadPool).let { getTtlScheduledExecutorService(newScheduledThreadPool).let {
assertTrue(it is ScheduledExecutorServiceTtlWrapper) if (noTtlAgentRun()) assertTrue(it is ScheduledExecutorServiceTtlWrapper)
assertTrue(isTtlWrapper(it)) assertEquals(noTtlAgentRun(), isTtlWrapper(it))
assertSame(newScheduledThreadPool, unwrap(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 @Test
fun test_null() { fun test_null_executors() {
assertNull(getTtlExecutor(null)) assertNull(getTtlExecutor(null))
assertNull(getTtlExecutorService(null)) assertNull(getTtlExecutorService(null))
assertNull(getTtlScheduledExecutorService(null)) assertNull(getTtlScheduledExecutorService(null))
assertFalse(isTtlWrapper(null)) assertFalse(isTtlWrapper(null))
assertNull(unwrap(null)) assertNull(unwrap<Executor>(null))
} }
} }
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))
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册