Pet*_*erM 5 java concurrency threadpool
我已经创建了一个包含4个工作线程的池来处理一些文件.在测试中,大约有200个.线程池版本已经比顺序执行快3倍,但还有改进的余地.
最大的瓶颈(忽略磁盘I/O)是我需要实例化一个新的MessageDigest对象.在单线程版本中我只有1.在这个版本中我有200.
我想知道的是,是否有可能在工作池中的线程有一个本地变量?那样(假设没有线程死掉),MessageDigest对象只有四个实例,而不是200个......
每个任务都需要摘要,所以我不确定是否有更好的方法来做到这一点......
我试图使用ThreadLocal对象,但我应该在哪里创建它?如果我在任务本身创建它,我猜它在任务完成时就会脱离上下文.每次创建新实例时.我的代码是:
ThreadLocal<GenerateSHA1> tl = new ThreadLocal<GenerateSHA1>();
hashMaker = tl.get();
if(hashMaker == null){
hashMaker = new GenerateSHA1();
tl.set(hashMaker);
}
Run Code Online (Sandbox Code Playgroud)
这是从任务的构造函数内部完成的.
UPDATE
好吧,让它成为静态的工作,因为对象不会丢失 - 但它现在突出显示了一个不同的问题.工作"任务"在主线程中创建,然后使用invokveAll()添加到ExecutorService.
关于如何解决这个问题的任何想法?
扩展ThreadLocal您的类并覆盖该initialValue()方法。默认情况下,它返回 null。
private static class ThreadLocalGenerateSHA1 extends
ThreadLocal<GenerateSHA1> {
@Override
protected GenerateSHA1 initialValue() {
return new GenerateSHA1();
}
}
private static final ThreadLocalGenerateSHA1 generateSHA1 = new ThreadLocalGenerateSHA1();
...
Run Code Online (Sandbox Code Playgroud)
在任务上,只需调用get()generateSHA1的方法即可。您不需要打电话set()。