Pie*_*Jan 7 java singleton thread-local
我在GlassFish上运行RESTful java后端.附加一个HTML5/JS前端,我可以将其放入webapp项目(然后将后端包含为依赖项),或者在不同位置的IIS Web服务器上运行.CORS不是问题.无论如何解决以下问题:
情况:
User1将无法从db/user1中删除值1,因为数据库路径已更改为db/user2且该数据库中没有值1.
public class DataAccess{
private static DataAccess dataaccess;
private String databasepath;
public static DataAccess getInstance() {
if (dataaccess == null) {
dataaccess = new DataAccess();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何修改getInstance()方法以使其充当单例,但仅在该用户的线程内?我看到了一些名为threadlocal的东西,但没有完全理解它,这可能是一个解决方案吗?
任何帮助肯定是值得赞赏的.
Bor*_*der 10
您可以ThreadLocal在工厂模式中使用该类:
public class DataAccess{
private static ThreadLocal<DataAccess> THREAD_LOCAL = new ThreadLocal() {
@Override
protected DataAccess initialValue() {
return new DataAccess();
}
};
private String databasepath;
public static DataAccess getInstance() {
return THREAD_LOCAL.get();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这会导致内存泄漏.因此,您需要使用Servlet过滤器在请求开始时设置值,然后在最后删除它,例如:
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
DataAccess.set(new DataAccess("SomeValue"));
try {
chain.doFilter(request, response);
} finally {
DataAcess.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
一旦你有一个class实现过滤器,你可以将它添加到你的web.xml:
<!--Filter for adding in dataccess objects-->
<filter>
<filter-name>DataccessFilter</filter-name>
<filter-class>my.package.DataccessFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>DataccessFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)
此页面提供了过滤器及其映射的示例.
你DataAccess会看起来像:
public class DataAccess{
private static ThreadLocal<DataAccess> THREAD_LOCAL = new ThreadLocal();
private String databasepath;
public DataAcess(final String databasepath) {
this.databasepath = databasepath;
}
public static DataAccess getInstance() {
return THREAD_LOCAL.get();
}
public static void set(final DataAccess dataAccess) {
THREAD_LOCAL.set(dataAccess);
}
public static void remove() {
THREAD_LOCAL.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
要非常小心,ThreadLocal因为它可能是Java中内存泄漏的头号原因.对于具有线程池的Web服务器,如果不正确清除它们,则可能会遇到更严重的错误.