java多线程(6)---ThreadLocal
2018-06-19 20:54
316 查看
ThreadLocal
什么是ThreadLocal?顾名思义它是local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
从线程的角度看,就好像每一个线程都完全拥有该变量。
注意:ThreadLocal不是用来解决共享对象的多线程访问问题的。
一、多线程共享成员变量
在多线程环境下,之所以会有并发问题,就是因为不同的线程会同时访问同一个共享变量,同时进行一系列的操作。1、例如下面的形式
//这个意思很简单,创建两个线程,a线程对全局变量+10,b线程对全局变量-10 public class MultiThreadDemo { public static class Number { private int value = 0; public void increase() throws InterruptedException { //这个变量对于该线程属于局部变量 value = 10; Thread.sleep(10); System.out.println("increase value: " + value); } public void decrease() throws InterruptedException { //同样这个变量对于该线程属于局部变量 value = -10; Thread.sleep(10); System.out.println("decrease value: " + value); } } public static void main(String[] args) throws InterruptedException { final Number number = new Number(); Thread a = new Thread(new Runnable() { @Override public void run() { try { number.increase(); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread b = new Thread(new Runnable() { @Override public void run() { try { number.decrease(); } catch (InterruptedException e) { e.printStackTrace(); } } }); a.start(); b.start(); } }
思考:可能运行的结果:
//运行结果(其中一种可能) 11 10 pool-1-thread-2 pool-1-thread-1 //说明已经实现了共享变量私有
运行结果
四、ThreadLocal的应用场景
最常见的ThreadLocal使用场景为 用来解决 数据库连接、Session管理等。1、 数据库连接管理
同一事务多DAO共享同一Connection,必须在一个共同的外部类使用ThreadLocal保存Connection。public class ConnectionManager { private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() { @Override protected Connection initialValue() { Connection conn = null; try { conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/test", "username", "password"); } catch (SQLException e) { e.printStackTrace(); } return conn; } }; public static Connection getConnection() { return connectionHolder.get(); } public static void setConnection(Connection conn) { connectionHolder.set(conn); } }
这样就保证了一个线程对应一个数据库连接,保证了事务。因为事务是依赖一个连接来控制的,如commit,rollback,都是数据库连接的方法。
2、Session管理
private static final ThreadLocal threadSession = new ThreadLocal(); public static Session getSession() throws InfrastructureException { Session s = (Session) threadSession.get(); try { if (s == null) { s = getSessionFactory().openSession(); threadSession.set(s); } } catch (HibernateException ex) { throw new InfrastructureException(ex); } return s; }
参考
1、【Java 并发】详解 ThreadLocal2、Java并发编程:深入剖析ThreadLocal
3、对ThreadLocal中的key和value
想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。少校【12】
相关文章推荐
- Java多线程--ThreadLocal
- Java多线程之详解ThreadLocal类(一)
- Java多线程(十三):深入剖析ThreadLocal
- Java多线程之ThreadLocal
- Java 多线程:ThreadLocal关键字
- Java多线程之ThreadLocal
- Java多线程10:ThreadLocal的作用及使用
- JAVA多线程系列--ThreadLocal详解
- Java多线程之详解ThreadLocal类(一)
- java多线程:5、线程范围内的数据共享_ThreadLocal
- 【Java多线程与并发库】6.ThreadLocal类及应用技巧
- java多线程之ThreadLocal
- Java多线程之详解ThreadLocal类(一)
- Java多线程——2 ThreadLocal
- 【Java多线程与并发库】6.ThreadLocal类及应用技巧
- Java 多线程:ThreadLocal关键字
- Java基础:多线程之线程范围内的数据共享ThreadLocal
- 【Java多线程与并发库】05 线程范围内共享变量ThreadLocal
- java多线程之ThreadLocal
- Java多线程有哪几种实现方式? Java中的类如何保证线程安全? 请说明ThreadLocal的用法和适用场景(面试题)