Java中的ThreadLocal
来源:互联网 发布:得益数据库营销案例 编辑:程序博客网 时间:2024/06/10 22:16
ThreadLocal其实,它就是一个容器,用于存放线程的局部变量。为每个线程保留一份变量副本。
我们来看下面的代码:
数据库连接工具
package com.xfl.concurrent;import java.sql.Connection;import java.sql.DriverManager;/** * Created by XFL * time on 2017/5/16 23:43 * description: */public class DBUtil { // 数据库配置 private static final String driver = "com.mysql.jdbc.Driver"; private static final String url = "jdbc:mysql://localhost:3306/shop"; private static final String username = "XFL"; private static final String password = "********"; // 定义一个数据库连接 private static Connection conn = null; // 获取连接 public static Connection getConnection() { try { Class.forName(driver); conn = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); } return conn; } // 关闭连接 public static void closeConnection() { try { if (conn != null) { conn.close(); } } catch (Exception e) { e.printStackTrace(); } }}
测试线程
package com.xfl.concurrent;import java.sql.Connection;import java.sql.SQLException;/** * Created by XFL * time on 2017/5/16 23:50 * description: */public class ClientThread extends Thread { private int wait; private String threadName; public ClientThread(int wait, String threadName) { this.wait = wait; this.threadName = threadName; } @Override public void run() { Connection connection = DBUtil.getConnection(); System.out.println("正在执行的线程: " + threadName); try { //模仿耗时操作任务 Thread.sleep(wait); } catch (InterruptedException e) { System.out.println(e); } try { //主要是为了验证数据库连接是否关闭,可以起到模仿数据库操作的效果 System.out.println("线程:" + threadName + " 的数据库连接是否关闭:" + connection.isClosed()); } catch (SQLException e) { System.out.println(e); } DBUtil.closeConnection(); }}
测试代码
package com.xfl.concurrent;/** * Created by XFL * time on 2017/5/16 23:34 * description:ThreadLocal线程的局部变量 * https://my.oschina.net/huangyong/blog/159489 */public class ThreadLocalTest { public static void main(String[] args) { //让线程1多等待一会,目的是为了让线程2和线程1拿到同一个数据库连接(同一个对象) Thread thread1 = new ClientThread(1500, "thread1"); thread1.start(); Thread thread2 = new ClientThread(500, "thread2"); thread2.start(); }}
运行结果:
我们看到线程2会把线程1的数据库连接关闭,原因很简单因为线程1和线程2共用了一个数据库连接,因为我们在DBUtil中定义的Connection是static,修改方法有很多中比如将Connection定义在方法内部,每次都去new一个,当然关闭的方法也要做修改,最好的做法是使用ThreadLocal,为每个线程保留一份Connection的副本,不同的线程不共用一个连接,就不会出现上面的问题。
修改后的DBUtil
package com.xfl.concurrent;import java.sql.Connection;import java.sql.DriverManager;/** * Created by XFL * time on 2017/5/16 23:43 * description: */public class DBUtil { // 数据库配置 private static final String driver = "com.mysql.jdbc.Driver"; private static final String url = "jdbc:mysql://localhost:3306/shop"; private static final String username = "XFL"; private static final String password = "********"; // 定义一个数据库连接 private static Connection conn = null; // 定义一个用于放置数据库连接的局部线程变量(使每个线程都拥有自己的连接) private static ThreadLocal<Connection> connContainer = new ThreadLocal<Connection>(); // 获取连接 public static Connection getConnection() { //从ThreadLocal中获取Connection Connection conn = connContainer.get(); try { Class.forName(driver); conn = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); }finally { //将 connContainer放入到ThreadLocal中 connContainer.set(conn); } return conn; } // 关闭连接 public static void closeConnection() { //获取Connection Connection conn = connContainer.get(); try { if (conn != null) { conn.close(); } } catch (Exception e) { e.printStackTrace(); }finally { //移除Connection connContainer.remove(); } }}
运行结果:
我们可以看到线程1和线程2之间不会相互影响了。
参考资料:https://my.oschina.net/huangyong/blog/159725
阅读全文
1 0
- Java中的ThreadLocal示例.
- 理解java中的ThreadLocal
- java中的ThreadLocal
- Java中的ThreadLocal类
- Java中的ThreadLocal类
- Java中的ThreadLocal
- 理解java中的ThreadLocal
- Java多线程中的ThreadLocal
- java线程中的ThreadLocal
- 理解Java中的ThreadLocal
- 谈谈Java中的ThreadLocal
- 谈谈Java中的ThreadLocal
- Java中的ThreadLocal对象
- Java中的ThreadLocal
- Java中的ThreadLocal
- JAVA中的ThreadLocal
- 谈谈Java中的ThreadLocal
- 谈谈Java中的ThreadLocal
- 将字符串中字符按出现自出升序输出
- 不用中间变量交换两个数
- ngixn负载均衡+tomcat+https配置
- 怎么用Android代码跳过局域网路由器登录,获取里面的数据网页源码
- 0516
- Java中的ThreadLocal
- TensorFlow3:构建卷积神经的MNIST
- MATLAB数组元素引用的三种方法
- 腾讯centos云服务器编码问题
- MySQL 半同步复制数据安全与一致性分析
- Sass中的mixins混合使用
- 20 QT里的声卡编程
- Java 观察者模式
- android 启动优化(一)