Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否已与ThreadLocal与InheritableThreadLocal同步?_Java_Multithreading_Concurrency_Vaadin - Fatal编程技术网

Java 是否已与ThreadLocal与InheritableThreadLocal同步?

Java 是否已与ThreadLocal与InheritableThreadLocal同步?,java,multithreading,concurrency,vaadin,Java,Multithreading,Concurrency,Vaadin,下面我将实现一个vaadin应用程序 应用程序的状态由多个工作线程修改。因此,为了通知应用程序其状态已更改,我添加了一个进度指示器 阅读progress indicator示例,我看到以下内容: // All modifications to Vaadin components should be synchronized // over application instance. For normal requests this is done

下面我将实现一个vaadin应用程序

应用程序的状态由多个工作线程修改。因此,为了通知应用程序其状态已更改,我添加了一个进度指示器

阅读progress indicator示例,我看到以下内容:

        // All modifications to Vaadin components should be synchronized
        // over application instance. For normal requests this is done
        // by the servlet. Here we are changing the application state
        // via a separate thread.
        synchronized (getApplication()) {
            prosessed();
        }
因此,基本上,我认为我只需修改对
getApplication
的调用即可获得我的应用程序的实例(只需调用
getCurrent
):

private static ThreadLocal currentApplication=new ThreadLocal();
@凌驾
公共void init(){
setCurrent(this);//这样我们就可以立即访问当前的应用程序
//初始化主窗口和其他东西
//注册一个事务侦听器,用每个请求更新我们的ThreadLocal
如果(getContext()!=null){
getContext().addTransactionListener(此);
}   
}
/**
*@返回当前应用程序实例
*/
公共静态MyApplication getCurrent(){
返回currentApplication.get();
}
问题是我的工作线程因饥饿而死,因为它无法获取应用程序上的互斥。 瓦丁论坛提供的一个解决方案是使用。这很有效,但我不明白为什么

从javadoc:

此类扩展了ThreadLocal,以提供来自的值的继承 父线程到子线程:创建子线程时 子线程接收所有可继承线程本地的初始值 父项具有值的变量。通常是孩子的价值观 将与父母的相同;但是,子对象的值可以是 通过重写 此类中的childValue方法

可继承的线程局部变量优先于普通线程使用 维护每线程属性时的线程局部变量 在变量中(例如,用户ID、事务ID)必须自动 传输到创建的任何子线程

我的工作线程无法获得锁,因为它没有收到初始值? 我是不是误解了什么? 除此之外,使用InheritableThreadLocal的潜在陷阱是什么


谢谢。

了解其工作原理的关键是ThreadLocal类中的方法:

static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
   return new ThreadLocalMap(parentMap);
}
它被设计为仅从线程构造函数调用。方法

protected Object childValue(Object parentValue)
of
InheritableThreadLocal
类用于将子线程中
InheritableThreadLocal
变量的初始值设置为父线程中
ThreadLocal
变量(作为参数传递)的函数。此方法在创建子线程之前从父线程内调用,默认实现将使子值与父线程的值相同,但我们可以重写
childValue()
方法将子值设置为父线程中具有值的
线程局部变量的父值的函数。默认情况下,
childValue()
返回相同的输入参数,但是对
childValue()
方法的重写也可能会更改此行为


因此,
InheritableThreadLocal
的工作原理几乎与
ThreadLocal
类似,它也有同样的同步陷阱。

我真的不明白,特别是最后一句以“So”开头的话。我不明白为什么这是前一段的结果。为什么使用ThreadLocal而不是InheritableThreadLocal会导致饥饿?
protected Object childValue(Object parentValue)