标签: thread-local

变量的同步和本地副本

我正在看一些具有以下习语的遗留代码:

Map<String, Boolean> myMap = someGlobalInstance.getMap();
synchronized (myMap) {
    item = myMap.get(myKey);
}
Run Code Online (Sandbox Code Playgroud)

我从Intelli-J的代码检查得到的警告是:

Synchronization on local variable 'myMap'
Run Code Online (Sandbox Code Playgroud)

这是适当的同步吗?为什么?

Map<String, Boolean> myMap = someGlobalInstance.getMap();
synchronized (someGlobalInstance.getMap()) {
    item = myMap.get(myKey);
}
Run Code Online (Sandbox Code Playgroud)

java synchronized intellij-idea thread-local

13
推荐指数
1
解决办法
4035
查看次数

如何强制Java线程关闭线程本地数据库连接

使用线程本地数据库连接时,线程存在时需要关闭连接.

这只能我可以覆盖调用线程的run()方法.即使这不是一个很好的解决方案,因为在退出时,我不知道该线程是否曾打开过连接.

问题实际上更为通用:如何强制线程在线程局部对象退出时调用某些终结方法.

我查看了java 1.5的源代码,发现线程本地映射设置为null,这最终会导致垃圾收集调用finalize(),但我不想指望垃圾收集器.

以下覆盖似乎是不可避免的,以确保关闭数据库连接:

@Override 
public void remove() {
    get().release(); 
    super.remove(); 
}
Run Code Online (Sandbox Code Playgroud)

其中,release()关闭数据库连接(如果已打开).但我们不知道线程是否曾使用过本地线程.如果此线程从未调用过get(),那么这里的工作就相当浪费:将调用ThreadLocal.initialValue(),在此线程上创建一个map等.

-

根据Thorbjørn的评论进一步澄清和举例:

java.lang.ThreadLocal是绑定到线程的对象的工厂类型.此类型具有对象的getter和工厂方法(通常由用户编写).当调用getter时,只有在此线程之前从未调用过它时才调用工厂方法.

使用ThreadLocal允许开发人员将资源绑定到线程,即使线程代码是由第三方编写的.

示例:假设我们有一个名为MyType的资源类型,我们希望每个线程只有一个.

在using类中定义:private static ThreadLocal resourceFactory = new ThreadLocal(){@ override protected MyType initialValue(){return new MyType(); }}

在此类的本地上下文中使用:public void someMethod(){MyType resource = resourceFactory.get(); resource.useResource(); }

get()只能在调用线程的生命周期中调用initialValue()一次.此时,MyType的实例将被实例化并绑定到此线程.此线程对get()的后续调用再次引用此对象.

经典用法示例是MyType是一些线程不安全的text/date/xml格式化程序.

但是这样的格式化程序通常不需要被释放或关闭,数据库连接也是如此,我使用java.lang.ThreadLocal来为每个线程建立一个数据库连接.

我看待它的方式,java.lang.ThreadLocal几乎是完美的.几乎是因为如果调用线程属于第三方应用程序,则无法保证资源的关闭.

我需要你的大脑绅士:通过扩展java.lang.ThreadLocal,我设法为每个线程绑定一个数据库连接,因为它的独占用途 - 包括我无法修改或覆盖的线程.我设法确保在线程因未捕获的异常而死的情况下关闭连接.

在正常线程退出的情况下,垃圾收集器关闭连接(因为MyType会覆盖finalize()).实际上它很快发生,但这并不理想. …

java thread-local resource-disposal

13
推荐指数
2
解决办法
8800
查看次数

企业应用程序中的ThreadLocal用法

如果我的Web应用程序和ejb应用程序位于同一台机器上(在同一个JVM上)并且所有ejb调用都是本地调用,那么ThreadLocal在将信息从Web传递到ejb时是否会使用创建任何问题?

如果ejb调用是远程的,任何解决方法?将ThreadLocal信息可以从Web应用程序到EJB应用程序?ThreadLocal在这种情况下使用是否合适?

java ejb thread-local java-ee

13
推荐指数
1
解决办法
8417
查看次数

WebApp中的静态ThreadLocal变量 - 是否存在任何安全/性能问题?

我正在研究和试验我的Java Web应用程序中的ThreadLocal变量.我使用ThreadLocal变量在请求之前存储用户名(从会话中收集),然后在请求后删除它.我通过在ServletFilter中调用静态实用程序方法来完成此操作.我不是简单地从会话中检索用户名的原因是因为我继承了一个系统,该系统具有长时间运行的进程,有时需要比会话超时允许的运行时间更长.我的想法是在处理请求之前获取用户名并将其存储在ThreadLocal变量中,这样我就可以在整个请求期间访问用户名,即使它花费的时间超过15分钟.

我的问题是:

这种设计是否存在任何安全/性能问题?如果有,那么什么是更好的解决方案?即使没有任何安全和/或性能问题,也欢迎更好的想法.我的解决方案中的代码段如下所示:

这是我的实用程序类,将在我的过滤器和我需要用户名的任何地方调用.

public abstract class UserUtil {
private static final ThreadLocal<String> threadUser = new ThreadLocal<String>();

public static String getUserId(){
    return threadUser.get();
}

public static void setUserId(String userId){
    threadUser.set(userId);
}

public static void removeUserId(){
    threadUser.remove();
}
}
Run Code Online (Sandbox Code Playgroud)

这是我的servlet过滤器,用于在请求之前设置用户名(并在请求后通过finally块清除它).

public class UserFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}

public void destroy() {
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    try {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        UserBean userBean …
Run Code Online (Sandbox Code Playgroud)

java session thread-local servlet-filters

12
推荐指数
1
解决办法
6262
查看次数

线程返回线程池后是否清除ThreadLocal对象?

ThreadLocal执行期间存储在存储中的内容是否会在线程返回ThreadPool时自动清除(如预期的那样)?

在我的应用程序中,我ThreadLocal在一些执行期间放入一些数据,但如果下次使用相同的Thread,那么我在ThreadLocal存储中找到过时的数据.

java multithreading thread-local threadpool

12
推荐指数
2
解决办法
4773
查看次数

使thread_local变量完全不稳定

我正在使用一个使用用户级上下文切换的运行时库(使用Boost :: Context),并且在使用thread_level变量时遇到了麻烦.考虑以下(简化)代码:

thread_local int* volatile tli;

int main()
{
    tli = new int(1);   // part 1, done by thread 1
    UserLevelContextSwitch();
    int li = *tli;      // part 2, done by thread 2
    cout << li;
}
Run Code Online (Sandbox Code Playgroud)

由于对thread_local变量有两次访问,因此编译器将main函数转换为沿着这些行的某些东西(与汇编相反):

register int** ptli = &tli; // cache address of thread_local variable
*ptli = new int(1);
UserLevelContextSwitch();
int li = **ptli;
cout << li;
Run Code Online (Sandbox Code Playgroud)

这似乎是一种合法的优化,因为volatile 的值tli不会缓存在寄存器中.但是, volatile 的地址tli实际上是缓存的,而不是从第2部分的内存中读取的.

这就是问题:在用户级上下文切换之后,执行第1部分的线程会转到其他位置.然后,第2部分由其他线程获取,该线程获得先前的堆栈和寄存器状态.但是现在正在执行第2部分的线程读取tli属于线程1的值.

我试图找出一种方法来阻止编译器缓存线程局部变量的地址,并且 …

c++ multithreading volatile thread-local boost-context

11
推荐指数
1
解决办法
641
查看次数

你知道在C++中获取线程本地存储的不同方法的一些性能测试吗?

我正在做一个广泛使用线程局部变量的库.你能指出一些基准测试来测试在C++中获取线程局部变量的不同方法的性能:

  • C++ 0x thread_local变量
  • 编译器扩展(Gcc __thread,...)
  • 提高:: threads_specific_ptr
  • 并行线程
  • 视窗
  • ...

C++ 0x thread_local在提供它的编译器上执行得更好吗?

c++ boost thread-local c++11

10
推荐指数
1
解决办法
333
查看次数

Valgrind errors with boost::thread_specific_ptr on GCC 8.3 + Linux

  • Ubuntu 19 running inside Docker
  • GCC 8.3
  • Boost 1.69
  • Valgrind 3.14.0

When the application is shutting down Valgrind reports these 3 issues:

==70== Mismatched free() / delete / delete []
==70==    at 0x483997B: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==70==    by 0x4870C89: check_free (dlerror.c:202)
==70==    by 0x4870C89: check_free (dlerror.c:186)
==70==    by 0x4870C89: free_key_mem (dlerror.c:221)
==70==    by 0x4870C89: __dlerror_main_freeres (dlerror.c:239)
==70==    by 0x4B59711: __libc_freeres (in /usr/lib/x86_64-linux-gnu/libc-2.29.so)
==70==    by 0x482E19E: _vgnU_freeres (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_core-amd64-linux.so)
==70==    by 0x4A0A3A9: __run_exit_handlers (exit.c:132)
==70==    by 0x4A0A3D9: exit (exit.c:139)
==70==    by …
Run Code Online (Sandbox Code Playgroud)

c++ boost pthreads boost-thread thread-local

10
推荐指数
1
解决办法
233
查看次数

为什么线程返回时 thread_local 变量没有被销毁?

为了更好地理解这个问题,代码如下:

// code 1
#include <iostream>
#include <thread>

struct tls_test {
    tls_test()
    { std::cout << "tls_test ctor\n"; }

    ~tls_test()
    { std::cout << "tls_test dtor\n"; }

    void print() const
    { std::cout << "tls_test print\n"; }
};

thread_local tls_test t;

void thread_1()
{
    std::cout << "thread_1 started\n";
    t.print();
    std::cout << "thread_1 return\n";
}

int main()
{
    std::thread trd{ thread_1 };
    trd.join();
    std::cout << "main return\n";
}
Run Code Online (Sandbox Code Playgroud)

我正在使用 TDM-GCC 和 Windows 10 来测试该程序。这是输出:

// code 1
#include <iostream>
#include <thread>

struct tls_test { …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading thread-local stdthread c++17

10
推荐指数
0
解决办法
324
查看次数

如何在c ++中初始化线程局部变量?

可能重复:
gcc中的C++ 11 thread_local - 替代方法
有没有办法使用GCC的__thread完全模拟thread_local?

我想使用c ++ 11 thread_local来创建和使用thread_local变量,但由于gcc尚不支持,我使用的是gcc特有的__thread.我声明变量的方式是

myClass
{
public:

  static __thread int64_t m_minInt;

};
__thread int64_t myClass::m_minInt = 100;
Run Code Online (Sandbox Code Playgroud)

当我编译它时,我得到一个错误

error: ‘myClass::minInt’ is thread-local and so cannot be dynamically initialized
Run Code Online (Sandbox Code Playgroud)

如何正确地做到这一点?

PS:gcc版本:4.6.3

c++ multithreading gcc thread-local thread-local-storage

9
推荐指数
1
解决办法
8946
查看次数