ExecutorService中的持久变量(Java)

Pet*_*erM 5 java concurrency threadpool

我已经创建了一个包含4个工作线程的池来处理一些文件.在测试中,大约有200个.线程池版本已经比顺序执行快3倍,但还有改进的余地.

最大的瓶颈(忽略磁盘I/O)是我需要实例化一个新的MessageDigest对象.在单线程版本中我只有1.在这个版本中我有200.

我想知道的是,是否有可能在工作池中的线程有一个本地变量?那样(假设没有线程死掉),MessageDigest对象只有四个实例,而不是200个......

每个任务都需要摘要,所以我不确定是否有更好的方法来做到这一点......

UPDATE

我试图使用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.

关于如何解决这个问题的任何想法?

Ste*_*han 3

扩展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()