jan*_*nin 3 java multithreading executor
我有一个问题,似乎接近Executors和线程池所做的,但我似乎无法让它完全适合.基本上我有工作人员需要花一些时间来初始化,我想要集中,一旦他们准备好了,我就用它们来做工作.我需要在一个线程中执行此操作:
worker = buildExpensiveWorker();
worker.doWork(work1);
worker.doWork(work2);
worker.doWork(work3);
...
Run Code Online (Sandbox Code Playgroud)
虽然Executor只允许我这样做:
doWork(work1);
doWork(work2);
doWork(work3);
...
Run Code Online (Sandbox Code Playgroud)
我需要编写自己的线程池吗?重写已经做得好的事情感觉真是太遗憾了.或者我是否需要用来ThreadLocal保存我的工作者,并从Runnablerun()方法中管理它们?
如果您在讨论实际初始化Thread对象之前可以使用它们,请查看ThreadPoolExecutor.setThreadFactory:
您可以以任何方式提供自己的实现创建线程,包括创建自定义线程子类和/或自定义初始化.
但是,我会说,如果你的初始化很昂贵,你应该尝试配置执行器以尽可能长时间保持实际线程的活动(即,设置保持活动时间相当高,并尝试启动所有线程你需要立即,并采取前面的打击).
编辑:使用本地线程(如评论中所述):
public class ThreadData {
public static final ThreadLocal<String> data = new ThreadLocal<String>();
}
public class InitializingThread extends Thread {
public InitializingThread(Runnable r) {
super(r);
}
public void run() {
ThreadData.data.set("foo");
super.run();
}
}
public class InitializingThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
return new InitializingThread(r);
}
}
ThreadPoolExecutor executor = ...;
executor.setThreadFactory(new InitializingThreadFactory());
executor.execute(...);
Run Code Online (Sandbox Code Playgroud)
然后在你的Runnable中:
public void run() {
String s = ThreadData.data.get();
}
Run Code Online (Sandbox Code Playgroud)
此外,这种方法(与使用Thread.currentThread()和强制转换相反)的优点是能够实际与任何Thread实现(包括默认)一起使用,或者没有线程(直接调用.run())在ThreadLocal中设置值后的方法).您还可以轻松地将"ThreadLocal"更改为"InheritableThreadLocal",并在向线程池提交任何内容之前将其设置一次.所有子线程都将从其父线程(创建池的线程)继承该值.
值得注意的是,给定线程的"run"方法只会执行一次,即使在线程池中也是如此,因此这可以保证初始化例程在每个线程的基础上发生.
| 归档时间: |
|
| 查看次数: |
670 次 |
| 最近记录: |