我正在按照这个线程本地模式实现一个 vaadin 应用程序。
应用程序的状态由多个工作线程修改。因此,为了通知应用程序其状态已更改,我添加了一个进度指示器。
阅读进度指示器示例,我看到了:
// 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<MyApplication> currentApplication = new ThreadLocal<MyApplication>();
@Override
public void init() {
setCurrent(this); // So that we immediately have access to the current application
// initialize mainWindow and other stuff
// Register a transaction listener that updates our ThreadLocal with each request
if (getContext() != null) {
getContext().addTransactionListener(this);
}
}
/**
* @return the current application instance
*/
public static MyApplication getCurrent() {
return currentApplication.get();
}
问题是我的工作线程死于饥饿,因为它无法获取应用程序上的互斥锁。vaadin 论坛提供的一种解决方案是使用InheritableThreadLocal。它有效,但我不明白为什么。
从 javadoc :
此类扩展 ThreadLocal 以提供从父线程到子线程的值继承:当创建子线程时,子线程接收父线程具有值的所有可继承线程局部变量的初始值。通常,孩子的价值观与父母的价值观相同;但是,通过覆盖此类中的 childValue 方法,可以使子项的值成为父项的任意函数。
当在变量中维护的每个线程属性(例如,用户 ID、事务 ID)必须自动传输到创建的任何子线程时,可继承的线程局部变量优先于普通线程局部变量使用。
我的工作线程无法获得锁,因为它没有收到初始值?我误解了什么吗?除了这个问题,我应该注意使用 InheritableThreadLocal 的潜在陷阱是什么?
谢谢。