Java ires同步(但可能便宜且不难编码)

Java ires同步(但可能便宜且不难编码),java,multithreading,caching,Java,Multithreading,Caching,也许还有其他的,取决于你到底做什么 在研究弱并发映射思想时,我发现它是在Guava的缓存中实现的 我使用当前线程作为软键,并提供了一个CacheLoader来自动为每个新线程创建资源 还添加了一个删除侦听器,以便在GC调用thread对象后,或者在关机期间调用invalidateAll()方法时,自动清理每个线程的资源 上面的大多数配置也可以在一个一行程序中完成(使用lambdas)。是绑定到线程的资源,还是可以从不同的线程使用它们,一次只有一个?它们不必绑定到特定的线程:)谁持有对Thread

也许还有其他的,取决于你到底做什么


在研究弱并发映射思想时,我发现它是在Guava的
缓存中实现的

我使用当前线程作为软键,并提供了一个
CacheLoader
来自动为每个新线程创建资源

还添加了一个删除侦听器,以便在GC调用
thread
对象后,或者在关机期间调用
invalidateAll()
方法时,自动清理每个线程的资源


上面的大多数配置也可以在一个一行程序中完成(使用lambdas)。

是绑定到线程的资源,还是可以从不同的线程使用它们,一次只有一个?它们不必绑定到特定的线程:)谁持有对
ThreadLocal
的强引用?
ThreadLocal
只是在我的WAR中的一个类的字段中。一个单独的
列表
用于保存
WeakReference
s(在
ThreadLocal
中)引用的所有资源实例(强引用)。这是为了防止每个
线程
引用的
线程本地映射
,具有到WAR类加载器的强引用链(从而导致泄漏)。线程不持有对
线程本地
实例的强引用。内部
ThreadLocalMap
使用弱引用。实际上是你造成了你试图解决的问题。这是我最后所走的大方向。看看我的答案。
public class Test {
    public static ThreadLocal<Test> test = ThreadLocal.withInitial(Test::new);
}
<%= Test.test.get() %>
Aug 21, 2015 5:56:11 PM org.apache.catalina.loader.WebappClassLoaderBase checkThreadLocalMapForLeaks
SEVERE: The web application [test] created a ThreadLocal with key of type [java.lang.ThreadLocal.SuppliedThreadLocal] (value [java.lang.ThreadLocal$SuppliedThreadLocal@54e69987]) and a value of type [test.Test] (value [test.Test@2a98020a]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
public class ClassValueTest extends ClassValue<Method> {
    @Override
    protected Method computeValue(Class<?> type) {
        System.out.println("computeValue");
        return Arrays.stream(type.getDeclaredMethods())
            .filter(m->Modifier.isPublic(m.getModifiers()))
            .findFirst().orElse(null);
    }
    public static void main(String... arg) throws Throwable {
        // create a collectible class:
        MethodHandles.Lookup l=MethodHandles.lookup();
        MethodType noArg = MethodType.methodType(void.class);
        MethodHandle println = l.findVirtual(
            PrintStream.class, "println", MethodType.methodType(void.class, String.class));
        Runnable r=(Runnable)LambdaMetafactory.metafactory(l, "run",
            println.type().changeReturnType(Runnable.class), noArg, println, noArg)
           .getTarget().invokeExact(System.out, "hello world");
        r.run();
        WeakReference<Class<?>> ref=new WeakReference<>(r.getClass());
        ClassValueTest test=new ClassValueTest();
        // compute and get
        System.out.println(test.get(r.getClass()));
        // verify that the value is cached, should not compute
        System.out.println(test.get(r.getClass()));
        // allow freeing
        r=null;
        System.gc();
        if(ref.get()==null) System.out.println("collected");
        // ensure that it is not our cache instance that has been collected
        System.out.println(test.get(String.class));
    }
}