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

add unwrap util method for TtlRunnable/TtlCallable/TtlTimerTask

上级 c6115448
......@@ -172,4 +172,40 @@ public final class TtlCallable<V> implements Callable<V>, TtlEnhanced {
}
return copy;
}
/**
* Unwrap {@link TtlCallable} to the original/underneath one.
* <p>
* this method is {@code null}-safe, when input {@code Callable} parameter is {@code null}, return {@code null};
* if input {@code Callable} parameter is not a {@link TtlCallable} just return input {@code Callable}.
*
* @since 2.10.2
*/
@Nullable
public static <T> Callable<T> unwrap(@Nullable Callable<T> callable) {
if (!(callable instanceof TtlCallable)) return callable;
else return ((TtlCallable<T>) callable).getCallable();
}
/**
* Unwrap {@link TtlCallable} to the original/underneath one.
* <p>
* Invoke {@link #unwrap(Callable)} for each element in input collection.
* <p>
* This method is {@code null}-safe, when input {@code Callable} parameter is {@code null}, return a empty list.
*
* @see #unwrap(Callable)
* @since 2.10.2
*/
@Nonnull
public static <T> List<Callable<T>> unwraps(@Nullable Collection<? extends Callable<T>> tasks) {
if (null == tasks) return Collections.emptyList();
List<Callable<T>> copy = new ArrayList<Callable<T>>();
for (Callable<T> task : tasks) {
if (!(task instanceof TtlCallable)) copy.add(task);
else copy.add(((TtlCallable<T>) task).getCallable());
}
return copy;
}
}
......@@ -176,4 +176,40 @@ public final class TtlRunnable implements Runnable, TtlEnhanced {
}
return copy;
}
/**
* Unwrap {@link TtlRunnable} to the original/underneath one.
* <p>
* this method is {@code null}-safe, when input {@code Runnable} parameter is {@code null}, return {@code null};
* if input {@code Runnable} parameter is not a {@link TtlRunnable} just return input {@code Runnable}.
*
* @since 2.10.2
*/
@Nullable
public static Runnable unwrap(@Nullable Runnable runnable) {
if (!(runnable instanceof TtlRunnable)) return runnable;
else return ((TtlRunnable) runnable).getRunnable();
}
/**
* Unwrap {@link TtlRunnable} to the original/underneath one for collection.
* <p>
* Invoke {@link #unwrap(Runnable)} for each element in input collection.
* <p>
* This method is {@code null}-safe, when input {@code Runnable} parameter is {@code null}, return a empty list.
*
* @see #unwrap(Runnable)
* @since 2.10.2
*/
@Nonnull
public static List<Runnable> unwraps(@Nullable Collection<? extends Runnable> tasks) {
if (null == tasks) return Collections.emptyList();
List<Runnable> copy = new ArrayList<Runnable>();
for (Runnable task : tasks) {
if (!(task instanceof TtlRunnable)) copy.add(task);
else copy.add(((TtlRunnable) task).getRunnable());
}
return copy;
}
}
......@@ -2,7 +2,7 @@ package com.alibaba.ttl;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.TimerTask;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import static com.alibaba.ttl.TransmittableThreadLocal.Transmitter.*;
......@@ -81,7 +81,7 @@ public final class TtlTimerTask extends TimerTask implements TtlEnhanced {
}
/**
* Factory method, wrap input {@link Runnable} to {@link TtlTimerTask}.
* Factory method, wrap input {@link TimerTask} to {@link TtlTimerTask}.
* <p>
* This method is idempotent.
*
......@@ -94,12 +94,12 @@ public final class TtlTimerTask extends TimerTask implements TtlEnhanced {
}
/**
* Factory method, wrap input {@link Runnable} to {@link TtlTimerTask}.
* Factory method, wrap input {@link TimerTask} to {@link TtlTimerTask}.
* <p>
* This method is idempotent.
*
* @param timerTask input {@link TimerTask}
* @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred.
* @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlTimerTask} is referred.
* @return Wrapped {@link TimerTask}
*/
@Nullable
......@@ -108,12 +108,12 @@ public final class TtlTimerTask extends TimerTask implements TtlEnhanced {
}
/**
* Factory method, wrap input {@link Runnable} to {@link TtlTimerTask}.
* Factory method, wrap input {@link TimerTask} to {@link TtlTimerTask}.
* <p>
* This method is idempotent.
*
* @param timerTask input {@link TimerTask}
* @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlRunnable} is referred.
* @param releaseTtlValueReferenceAfterRun release TTL value reference after run, avoid memory leak even if {@link TtlTimerTask} is referred.
* @param idempotent is idempotent or not. {@code true} will cover up bugs! <b>DO NOT</b> set, only when you know why.
* @return Wrapped {@link TimerTask}
*/
......@@ -128,4 +128,40 @@ public final class TtlTimerTask extends TimerTask implements TtlEnhanced {
}
return new TtlTimerTask(timerTask, releaseTtlValueReferenceAfterRun);
}
/**
* Unwrap {@link TtlTimerTask} to the original/underneath one.
* <p>
* this method is {@code null}-safe, when input {@code TimerTask} parameter is {@code null}, return {@code null};
* if input {@code TimerTask} parameter is not a {@link TtlTimerTask} just return input {@code TimerTask}.
*
* @since 2.10.2
*/
@Nullable
public static TimerTask unwrap(@Nullable TimerTask timerTask) {
if (!(timerTask instanceof TtlTimerTask)) return timerTask;
else return ((TtlTimerTask) timerTask).getTimerTask();
}
/**
* Unwrap {@link TtlTimerTask} to the original/underneath one.
* <p>
* Invoke {@link #unwrap(TimerTask)} for each element in input collection.
* <p>
* This method is {@code null}-safe, when input {@code TimerTask} parameter is {@code null}, return a empty list.
*
* @see #unwrap(TimerTask)
* @since 2.10.2
*/
@Nonnull
public static List<TimerTask> unwraps(@Nullable Collection<? extends TimerTask> tasks) {
if (null == tasks) return Collections.emptyList();
List<TimerTask> copy = new ArrayList<TimerTask>();
for (TimerTask task : tasks) {
if (!(task instanceof TtlTimerTask)) copy.add(task);
else copy.add(((TtlTimerTask) task).getTimerTask());
}
return copy;
}
}
......@@ -138,7 +138,7 @@ public final class TtlExecutors {
}
/**
* check the {@link ThreadFactory} is {@link DisableInheritableThreadFactory} or not.
* check the {@link ThreadFactory} is {@link DisableInheritableThreadFactory} or not.
*
* @see DisableInheritableThreadFactory
* @since 2.10.0
......
......@@ -168,6 +168,24 @@ class TtlCallableTest {
assertThat(callList[3], instanceOf(TtlCallable::class.java))
}
@Test
fun test_unwrap() {
assertNull(TtlCallable.unwrap<String>(null))
val callable = Callable { "hello" }
val ttlCallable = TtlCallable.get(callable)
assertSame(callable, TtlCallable.unwrap(callable))
assertSame(callable, TtlCallable.unwrap(ttlCallable))
assertEquals(listOf(callable), TtlCallable.unwraps(listOf(callable)))
assertEquals(listOf(callable), TtlCallable.unwraps(listOf(ttlCallable)))
assertEquals(listOf(callable, callable), TtlCallable.unwraps(listOf(ttlCallable, callable)))
assertEquals(listOf<Callable<String>>(), TtlCallable.unwraps<String>(null))
}
companion object {
private val executorService = Executors.newFixedThreadPool(3).also { expandThreadPool(it) }
......
......@@ -294,6 +294,24 @@ class TtlRunnableTest {
assertThat(taskList[3], instanceOf(TtlRunnable::class.java))
}
@Test
fun test_unwrap() {
assertNull(TtlRunnable.unwrap(null))
val runnable = Runnable {}
val ttlRunnable = TtlRunnable.get(runnable)
assertSame(runnable, TtlRunnable.unwrap(runnable))
assertSame(runnable, TtlRunnable.unwrap(ttlRunnable))
assertEquals(listOf(runnable), TtlRunnable.unwraps(listOf(runnable)))
assertEquals(listOf(runnable), TtlRunnable.unwraps(listOf(ttlRunnable)))
assertEquals(listOf(runnable, runnable), TtlRunnable.unwraps(listOf(ttlRunnable, runnable)))
assertEquals(listOf<Runnable>(), TtlRunnable.unwraps(null))
}
companion object {
private val executorService = Executors.newFixedThreadPool(3).also { expandThreadPool(it) }
......
package com.alibaba.ttl
import org.junit.Assert.*
import org.junit.Test
import java.util.*
class TtlTimerTaskTest {
@Test
fun test_get() {
assertNull(TtlTimerTask.get(null))
val timerTask = object : TimerTask() {
override fun run() {}
}
val ttlTimerTask = TtlTimerTask.get(timerTask)
assertTrue(ttlTimerTask is TtlTimerTask)
}
@Test
fun test_unwrap() {
assertNull(TtlTimerTask.unwrap(null))
val timerTask = object : TimerTask() {
override fun run() {}
}
val ttlTimerTask = TtlTimerTask.get(timerTask)
assertSame(timerTask, TtlTimerTask.unwrap(timerTask))
assertSame(timerTask, TtlTimerTask.unwrap(ttlTimerTask))
assertEquals(listOf(timerTask), TtlTimerTask.unwraps(listOf(timerTask)))
assertEquals(listOf(timerTask), TtlTimerTask.unwraps(listOf(ttlTimerTask)))
assertEquals(listOf(timerTask, timerTask), TtlTimerTask.unwraps(listOf(ttlTimerTask, timerTask)))
assertEquals(listOf<TimerTask>(), TtlTimerTask.unwraps(null))
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册