我所追求的是一种配置线程池使用的兼容方式.理想情况下,其余代码不应受到影响.我可以使用一个线程池与1个线程,但这不是我想要的.有任何想法吗?
ExecutorService es = threads == 0 ? new CurrentThreadExecutor() : Executors.newThreadPoolExecutor(threads);
// es.execute / es.submit / new ExecutorCompletionService(es) etc
Run Code Online (Sandbox Code Playgroud)
Nam*_*ter 76
您可以使用番石榴MoreExecutors.newDirectExecutorService(),或者MoreExecutors.directExecutor()如果您不需要ExecutorService.
如果包含番石榴太重了,你可以实现几乎同样好的东西:
public final class SameThreadExecutorService extends ThreadPoolExecutor {
private final CountDownLatch signal = new CountDownLatch(1);
private SameThreadExecutorService() {
super(1, 1, 0, TimeUnit.DAYS, new SynchronousQueue<Runnable>(),
new ThreadPoolExecutor.CallerRunsPolicy());
}
@Override public void shutdown() {
super.shutdown();
signal.countDown();
}
public static ExecutorService getInstance() {
return SingletonHolder.instance;
}
private static class SingletonHolder {
static ExecutorService instance = createInstance();
}
private static ExecutorService createInstance() {
final SameThreadExecutorService instance
= new SameThreadExecutorService();
// The executor has one worker thread. Give it a Runnable that waits
// until the executor service is shut down.
// All other submitted tasks will use the RejectedExecutionHandler
// which runs tasks using the caller's thread.
instance.submit(new Runnable() {
@Override public void run() {
boolean interrupted = false;
try {
while (true) {
try {
instance.signal.await();
break;
} catch (InterruptedException e) {
interrupted = true;
}
}
} finally {
if (interrupted) {
Thread.currentThread().interrupt();
}
}
}});
return Executors.unconfigurableScheduledExecutorService(instance);
}
}
Run Code Online (Sandbox Code Playgroud)
ove*_*ink 60
这是一个非常简单Executor(不是ExecutorService,介意你)的实现,只使用当前线程.从"实践中的Java并发"(基本阅读)中窃取这一点.
public class CurrentThreadExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
}
Run Code Online (Sandbox Code Playgroud)
ExecutorService 是一个更复杂的界面,但可以用相同的方法处理.
Eri*_*ner 12
我写了一个ExecutorService基于AbstractExecutorService.
/**
* Executes all submitted tasks directly in the same thread as the caller.
*/
public class SameThreadExecutorService extends AbstractExecutorService {
//volatile because can be viewed by other threads
private volatile boolean terminated;
@Override
public void shutdown() {
terminated = true;
}
@Override
public boolean isShutdown() {
return terminated;
}
@Override
public boolean isTerminated() {
return terminated;
}
@Override
public boolean awaitTermination(long theTimeout, TimeUnit theUnit) throws InterruptedException {
shutdown(); // TODO ok to call shutdown? what if the client never called shutdown???
return terminated;
}
@Override
public List<Runnable> shutdownNow() {
return Collections.emptyList();
}
@Override
public void execute(Runnable theCommand) {
theCommand.run();
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用RejectedExecutionHandler在当前线程中运行任务.
public static final ThreadPoolExecutor CURRENT_THREAD_EXECUTOR = new ThreadPoolExecutor(0, 0, 0, TimeUnit.DAYS, new SynchronousQueue<Runnable>(), new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
r.run();
}
});
Run Code Online (Sandbox Code Playgroud)
你只需要其中一个.
为了测试目的,我不得不使用相同的“ CurrentThreadExecutorService”,尽管所有建议的解决方案都不错(特别是提到Guava方式的解决方案),但我想出了与Peter Lawrey 在这里建议的类似的东西。
正如Axelle Ziegler 在此处提到的那样,不幸的是,Peter的解决方案实际上无法正常工作,因为ThreadPoolExecutor在maximumPoolSize构造函数参数上引入了检查(即maximumPoolSize,不可能是<=0)。
为了避免这种情况,我做了以下工作:
private static ExecutorService currentThreadExecutorService() {
CallerRunsPolicy callerRunsPolicy = new ThreadPoolExecutor.CallerRunsPolicy();
return new ThreadPoolExecutor(0, 1, 0L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), callerRunsPolicy) {
@Override
public void execute(Runnable command) {
callerRunsPolicy.rejectedExecution(command, this);
}
};
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31285 次 |
| 最近记录: |