语境:
static ThreadLocal<MyType> threadLocalMyType = ...
Run Code Online (Sandbox Code Playgroud)
我想要的是说:
for (ThreadLocalEntry e: threadLocalMyType.getMapLikeThing() {
// Thread t = e.getKey();
// I don't need the thread value right now, but it might be useful for
// something else.
MyType theMyType = e.getValue();
// [...do something with theMyType...]
}
Run Code Online (Sandbox Code Playgroud) 外行人说,当有人说某个对象是Java中的线程单一单例时,它意味着什么?我正在参加有关Java Server Faces的讲座,每次谈到FacesContext时 - 讲师总是提醒我们这是一个线程单一的单身人士.
有什么区别
request.getSession()
Run Code Online (Sandbox Code Playgroud)
和
getThreadLocalRequest().getSession()
Run Code Online (Sandbox Code Playgroud)
我维护的应用程序似乎使用第一个用于直接Servlets,第二个用于通过GWT-RPC实现的任何东西,GWT-RPC本身扩展了servlet.
在pyparsing中我遇到了这个错误
from pyparsing import Word,alphas,nums,Or,Regex,StringEnd
ws = Regex('\s*')
dot = "."
w = Word(alphas) + (ws | dot) + StringEnd()
w.leaveWhitespace()
w.parseString('AMIT.')
Run Code Online (Sandbox Code Playgroud)
返回以下错误:
ParseException: Expected end of text (at char 4), (line:1, col:5)
Run Code Online (Sandbox Code Playgroud) 我写了一个授权系统,它依赖于代表当前用户的对象.为了简化编程并提高性能,我希望在用户登录后将这些对象保存在ThreadLocal中.
它看起来像这样:
public class UserCache {
private static final ThreadLocal<User> cache = new ThreadLocal<User>();
public User getCurrentUser() {
return cache.get();
}
public void setCurrentUser(User user) {
cache.set(user);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经读过静态元素使聚类成问题.如果我在每个群集节点上都有一个UserCache,则它们都有自己的缓存对象与其他节点上的缓存对象不同步.对?UserCache
是单例的经典候选者,因为应用程序只需要它的一个实例.但据我所知,@ Singleton EJB在集群中具有相同的行为.
那么如何使UserCache在EJB 3.1(Java EE 6)环境中可以集群?
从答案中提取的解决方案:
我有一个使用hibernate的web应用程序,由于某种原因,每个线程(httprequest或与排队相关的其他线程)使用不同的会话.我已经实现了一个HibernateSessionFactory
看起来像这样的类:
public class HibernateSessionFactory {
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new AnnotationConfiguration();
private static org.hibernate.SessionFactory sessionFactory;
static {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {}
}
private HibernateSessionFactory() {}
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();//This method basically does what the static init block does
}
session = …
Run Code Online (Sandbox Code Playgroud) 我在Servlet中使用了很多SimpleDateFormat对象.不幸的是,SimpleDateFormat不是线程安全的.因此,我考虑用ThreadLocal包装它以促进SimpleDateFormat对象的重用.我写了一个util-class来启用它:
public class DateUtil {
private final static ThreadLocal<SimpleDateFormat> dateFormat = new ThreadLocal<SimpleDateFormat>() {
return new SimpleDateFormat();
}
public static SimpleDateFormat get () {
return dateFormat.get();
}
}
Run Code Online (Sandbox Code Playgroud)
实际上,这似乎导致内存泄漏.关闭我的webapp时,Tomcat会记录以下错误消息:
严重:Web应用程序[]使用[null]类型的键创建了一个ThreadLocal(值[com.example.util.DateUtil$2@50242f7d]),类型为[java.text.SimpleDateFormat](value [java.text] .SimpleDateFormat @ d91b489b])但在Web应用程序停止时无法将其删除.这很可能造成内存泄漏.
我理解内存泄漏的原因,但是在Servlet中处理SimpleDateFormat-objects(或任何其他非线程安全对象)的最佳方法是什么?
在我的DAO
课程中,我有一个参考EntityManager
.我想EntityManager
通过使用来访问线程安全的ThreadLocal
.
到目前为止,我的尝试只导致了NullPointerException
s,我似乎无法找到一个体面的例子.
有人可以给我一个例子或指出我正确的方向吗?
更新:我已经尝试过BalusC的建议,但是当我同时通过JSF和JAX-RS webservice访问DAO时,我仍然遇到错误:
org.hibernate.exception.GenericJDBCException: could not load an entity
java.sql.SQLException: You can't operate on a closed Connection!!!
java.lang.NullPointerException
at com.mchange.v2.c3p0.impl.NewProxyConnection.prepareStatement
Run Code Online (Sandbox Code Playgroud)
我正在使用C3P0,所以我不知道为什么闭合连接是个问题.
update2:BalusC的最后评论似乎解决了我的问题:At least, you should not have a single instance of the DAO class shared throughout the application. Create a new one on every request.
我正在使用ThreadLocal
变量(通过Clojure的变量,但以下内容对于ThreadLocal
Java中的普通变量是相同的)并且经常遇到这样的问题:我无法确定某个代码路径是在同一个线程上还是在另一个线程.对于我控制下的代码,这显然不是一个大问题,但对于多态第三方代码,有时甚至没有办法静态地确定是否可以安全地假设单线程执行.
我倾向于认为这是ThreadLocal
s 的固有问题,但我想听听一些如何以安全的方式使用它们的建议.
如果我有一个字符串
"this is a string"
Run Code Online (Sandbox Code Playgroud)
如何缩短它以使我在单词之间只有一个空格而不是多个空格?(空格的数量是随机的)
"this is a string"
Run Code Online (Sandbox Code Playgroud) 以下类显示了与实际用例类似的内容.它始终为同一个线程返回相同的实例.
public class LookingForName {
private static final ThreadLocal<Something> threadLocal =
new ThreadLocal<Something>(){
@Override
protected Something initialValue() {
return getSomethingSpecial(); // not relevant
}
};
/**
* @return always the same instance of "Something" for the current thread.
*/
public static Something getInstance() {
return threadLocal.get();
}
}
Run Code Online (Sandbox Code Playgroud)
你怎么称呼它?它是"工厂"吗?"价值持有者"?"ThreadLocalStore"?
java design-patterns naming-conventions thread-local factory-pattern
我有一个类MyThread,它实现了Callable <String>.该类有一个构造函数,它接受像blockqueue和其他参数.在我的主类中,我使用新的阻塞队列和其他参数来实例化此类MyThread.此外,我维护两个映射,一个用MyThread参考保持一个唯一参数作为键,另一个用同一个唯一键保持阻塞队列引用.
在此过程中,我从hashmap获取此阻塞队列,添加我的自定义消息并获取相应的MyThread实例并提交到ThreadPoolTaskExecutor(Spring版本).
据我所知,每个线程都应该获得自己的值副本(如阻塞队列等),因为我在构造过程中传递它们,稍后使用ThreadPoolTaskExecutor.submit(myThreadObj)创建一个线程.我只是想知道是否有人可以确认这是否正确或者我是否需要在这种情况下使用ThreadLocal.到目前为止测试,我没有遇到问题,但后来我还没有进行负载测试.
提前致谢.
我有一个Vaadin应用程序,当你同时运行两个应用程序实例时,我会遇到一些奇怪的行为(一个在FF中,另一个在IE中).我已经删除了大多数静态对象(这些导致应用程序在与另一个打开的应用程序并行使用时完全重新加载),现在我可以正常地与UI进行交互,而无需完全重置.但是,我现在注意到我在两个接口中只获得了一个用户的数据.我假设这是由我用来管理一些数据缓存和SOAP连接的单例对象引起的.我想知道它是单独的模式本身导致奇怪的输出还是它只是我保持的静态实例对象?
我尝试将ThreadLocal与我的单例一起使用,但是当我尝试在我的单例函数中使用它们时,我的所有变量都是null.目前我的单身人士包含了这个,这可能非常糟糕,因为它不起作用.
private static ThreadLocal<SoapClient> instance = new ThreadLocal<SoapClient>();
public static synchronized SoapClient getInstance(){
if (instance.get() == null) {
instance.set(new SoapClient());
}
return instance.get();
}
Run Code Online (Sandbox Code Playgroud)
我选择了一个单例对象,所以我总是可以访问我的应用程序实例中的缓存数据和我的用户的soap连接,而我能想到的另一种方法就是在某个地方有一个静态对象,但是静态关键字似乎首先是我所有问题的原因.有什么方法可以解决这个问题还是有其他原因导致它?