简体   繁体   English

将ThreadLocal用于JDBC连接是一种好习惯吗?

[英]Is it good practice to use ThreadLocal for JDBC Connections?

I am not sure if I get this abous ThreadLocals. 我不确定我是否得到这个ThreadLocals。 Sometimes you can read that a common practice is to make JDBC connections as ThreadLocals so each thread gets its own copy of the connection. 有时您会读到一种常见的做法是将JDBC连接作为ThreadLocals建立,以便每个线程都有自己的连接副本。 Let´s assume the socket below is a JDBC connection. 假设下面的套接字是JDBC连接。 Then I do: 然后我做:

public ThreadLocalSocket() throws IOException {

    Runnable runnable = new Runnable() {

        ThreadLocal<Socket> threadLocal = new ThreadLocal<>();
        @Override
        public void run() {
            try {
                threadLocal.set(new Socket("www.google.com", 80));
            } catch (IOException e) {e.printStackTrace();}

            Thread thread = Thread.currentThread();
            for (int j = 0; j < 10 ; j++) {

                Socket sock = threadLocal.get();
                if (thread.getName().equals("t1")) {
                    if (!sock.isClosed()) {
                        try {
                            sock.close();
                        } catch (IOException e) {e.printStackTrace();}
                    }
                }
                System.out.println("Thread: " + thread.getName()+  ", is closed? " + sock.isClosed() + ", sock hashCode = " + sock.hashCode());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {e.printStackTrace();}
            }
        }
    };

    Thread t1 = new Thread(runnable);
    t1.setName("t1");
    Thread t2 = new Thread(runnable);
    t2.setName("t2");

    t1.start();
    t2.start();
}

Why cannot I simply do this without ThreadLocals? 为什么没有ThreadLocals我不能简单地做到这一点? The behaviour is exactly the same in the following code snippet as the code example above: 下面的代码片段中的行为与上面的代码示例完全相同:

public ThreadLocalSocket() throws IOException {

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Socket socket = null;
            try {
                socket = new Socket("www.google.com", 80);
            } catch (IOException e) {e.printStackTrace();}

            Thread thread = Thread.currentThread();
            for (int j = 0; j < 10 ; j++) {
                if (thread.getName().equals("t1")) {
                    if (!socket.isClosed()) {
                        try {
                            socket.close();
                        } catch (IOException e) {e.printStackTrace();}
                    }
                }
                System.out.println("Thread: " + thread.getName()+  ", is closed? " + socket.isClosed() + ", socket hashCode = " + socket.hashCode());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {e.printStackTrace();}
            }
        }
    };

    Thread t1 = new Thread(runnable);
    t1.setName("t1");
    Thread t2 = new Thread(runnable);
    t2.setName("t2");

    t1.start();
    t2.start();
}

Yes, in your use case, it's pretty useless. 是的,在您的用例中,它几乎没有用。

The javadoc of ThreadLocal states ThreadLocal状态的Javadoc

ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (eg, a user ID or Transaction ID). ThreadLocal实例通常是希望将状态与线程关联的类中的私有静态字段(例如,用户ID或事务ID)。

The typical use case is to have the ThreadLocal as a kind of global member so that you don't have to pass around the referenced value. 典型的用例是将ThreadLocal作为一种全局成员,这样您就不必传递引用的值。 You expose it through some static methods and every piece of code you write has access to it without having to have it injected every time. 您通过一些static方法公开它,并且您编写的每一段代码都可以访问它,而不必每次都注入它。


For example, Spring MVC provides the class RequestContextHolder which keeps a ThreadLocal reference to a ServletRequest object. 例如,Spring MVC提供了RequestContextHolder类,该类保留对ServletRequest对象的ThreadLocal引用。 Since servlet containers typically (ie. not async mode) work by handling the request in a single thread, and instead of having to pass around the ServletRequest to every single component in the handling flow, Spring sets it once in the RequestContextHolder and other components have access to it through static helper methods (really just the attributes of the request). 由于Servlet容器通常(即非异步模式)通过在单个线程中处理请求而工作,而不是必须将ServletRequest传递给处理流程中的每个单个组件,因此Spring在RequestContextHolder对其进行一次设置,而其他组件具有通过static助手方法(实际上只是请求的属性)对其进行访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM