5

我有一个 ThreadLocal 变量。我想这样使用它:

ThreadLocal<AutoCloseable> threadLocal = new ThreadLocal<AutoCloseable>(); // pseudocode
ForkJoinPool fj = new ForkJoinPool(nThreads);
fj.submit(
    () -> myStream.parallel().forEach(e -> {
        /*I want to use the thread local autocloseable here, 
          but how do I close it when this parallel processing is done?*/
    })
);
4

2 回答 2

8

ThreadLocal 在使用它们的线程死亡后关闭。如果你想控制这个,你需要使用地图。

// do our own thread local resources which close when we want.
Map<Thread, Resource> threadLocalMap = new ConcurrentHashMap<>();

fj.submit(
() -> myStream.parallel().forEach(e -> {
     Resource r = threadLocalMap.computeIfAbsent(Thread.currentThread(), t -> new Resource();
    // use the thread local autocloseable here, 
})

// later once all the tasks have finished.
// close all the thread local resources when the parallel processing is done
threadLocalMap.values().forEach(Utils::closeQuietly);

通常有一种方法可以在不引发异常的情况下关闭资源。Chronicle 有一个,但许多其他库也有。

public static void closeQuietly(Closeable c) {
    if (c != null) {
       try {
           c.close();
       } catch (IOException ioe) {
           // ignore or trace log it
       }
    }
}

很可能您的项目中已经有一种方法可以做到这一点 https://www.google.co.uk/search?q=public+static+void+closequietly+Closeable

于 2018-11-30T13:53:33.513 回答
-1

您似乎想使用某种共享资源。所以要么不使用ThreadLocal(因为每个线程都有自己的实例(或 null))并等到每个任务完成

ForkJoinTask task=fj.submit(
    () -> myStream.parallel().forEach(e -> {
//whatever
    })
);
task.get()///wait - timeout would be good here
resource.close();// close that shared resource - wraping all of that with try-with-resources woudl work as well

.

或者只是像序列化代码一样使用该资源 - 使用它并关闭它forEach

于 2018-11-30T13:57:39.147 回答