优缺点和使用注意事项:
/* * ThreadLocal 用于每一个线程都有一个次线程对应的副本。“以空间换时间” 占用内存,提高效率,节约处理时间,同时保证事物一致性 * ThreadLocal防止内存泄漏的做法-->弱引用:WeakReference extends WeakReference<ThreadLocal> * 弱引用:引用对象如果不工作,JVM扫面到此现象后会回收引用数值,节省内存 * 强引用:eg String name = "zhangsan"; 一般对象如果不extends WeakReference都是强引用对象,特点是引用不消失,即使引用不工作了 * 引用值仍旧存在内存,不会被JVM回收掉 * * 写代码建议: 使用ThreadLocal后,可以手动调用其remove()方法。 * */
业务要求:
多线程下,实现线程内,多业务下数据共享使用; 实现线程之间数据彼此隔离
应用案例: 银行多人汇款
图:
应用代码模拟---> 获取线程数据conn
public class ConnectionManager { private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); private ConnectionManager(){} public static Connection getInstance(){ try { Connection conn = threadLocal.get(); if(conn == null){ conn = DriverManager.getConnection("");//获取数据库连接对象 threadLocal.set(conn); } return conn; } catch (SQLException e) { e.printStackTrace(); } return null; } }
要点: 使用map将线程和线程内公共数据绑定起来
代码1 自定义实现:
package thread; import java.util.HashMap; import java.util.Map; import java.util.Random; /** * 1 实现线程范围内的数据共享 * 2 实现线程之间的数据隔离 * 3 使用map对象,将每个线程产生的数据放在map中,业务方法中 仅仅获取当前线程下的共享数据 达到2的目的 * * @author zm * *测试结果: Thread-0 has put data 757103510 A from Thread-0 the data is: 757103510 B from Thread-0 the data is: 757103510 Thread-1 has put data -150123253 A from Thread-1 the data is: -150123253 B from Thread-1 the data is: -150123253 */ public class ScopeShareDataInThread { // public static int sharedata; public static Map map = new HashMap(); public static void main(String[] args) { final Businness businness = new Businness(); for(int i=0; i<2; i++) { new Thread(new Runnable(){ @Override public void run() { sharedata = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has put data " + sharedata); map.put(Thread.currentThread(), sharedata); businness.business1(sharedata,map); businness.business2(sharedata,map); } }).start(); } } } class Businness { // 业务1 public void business1(int data,Map map){ System.out.println("A from " + Thread.currentThread().getName() + " the data is: " + map.get(Thread.currentThread())); } // 业务2 public void business2(int data,Map map){ System.out.println("B from " + Thread.currentThread().getName() + " the data is: " + map.get(Thread.currentThread())); } }
代码2 使用JDK提供的ThreadLocal类:
package thread; import java.util.HashMap; import java.util.Map; import java.util.Random; /** * 使用jdk提供的类来实现 线程内数据共享 线程间数据隔离 * * threadLocal.set(sharedata) 会把数据放在当前线程中 * threadLocal.get() 回从当前线程中得到存放的数据 * * 其实 threadLocal = map.put(Thread.currentThread(), youdata); * * 测试结果: Thread-1 has put data 193003072 A from Thread-1 the data is: 193003072 B from Thread-1 the data is: 193003072 Thread-0 has put data -2012177886 A from Thread-0 the data is: -2012177886 B from Thread-0 the data is: -2012177886 * @author zm * */ public class MyThreadLocal { // public static ThreadLocal threadLocal = new ThreadLocal(); public static int sharedata; public static void main(String[] args) { final Businness1 businness = new Businness1(); for(int i=0; i<2; i++) { new Thread(new Runnable(){ @Override public void run() { sharedata = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has put data " + sharedata); threadLocal.set(sharedata); businness.business1(threadLocal); businness.business2(threadLocal); } }).start(); } } } class Businness1 { // 业务1 public void business1(ThreadLocal threadLocal){ System.out.println("A from " + Thread.currentThread().getName() + " the data is: " + threadLocal.get()); } // 业务2 public void business2(ThreadLocal threadLocal){ System.out.println("B from " + Thread.currentThread().getName() + " the data is: " + threadLocal.get()); } }
脑图:
相关推荐
与传统的使用`synchronized`关键字或`Lock`接口来实现线程同步不同,ThreadLocal提供了另一种解决线程安全问题的思路——即为每个线程创建独立的变量副本,避免了线程间的变量共享所带来的同步问题,从而提高了程序...
- **并发工具类**:在JDK 1.5之前,书中介绍了Semaphore、Barrier等并发工具,它们用于控制对共享资源的访问。 - **死锁、活锁和饥饿**:讨论了并发编程中可能出现的这些问题及其避免方法。 - **线程安全的数据...
JDK1.5及其更高版本提供了多种线程安全的Map实现,如`ConcurrentHashMap`和使用`synchronized`关键字来确保线程安全。 #### 类加载器模型 Java的类加载机制包括启动类加载器、扩展类加载器和应用类加载器三个层次。...
- **线程变量管理器**:通过ThreadLocal类来实现线程变量的管理,以解决多线程环境下的数据共享问题。 - **事务管理**:深入讨论了事务的基本概念、为何需要事务、事务的隔离级别等内容,并重点介绍了Spring框架中...
- **ThreadLocal原理**:每个线程拥有独立的副本,避免了线程间的共享和竞争。 - **Synchronized与Lock**:`Synchronized`关键字提供内置锁,而`Lock`接口提供更灵活的锁定机制。 - **ConcurrentHashMap**:在JDK 8...