JAVA网关如何做线程池隔离 java线程隔离详解

您所在的位置:网站首页 线程池如何保证线程存活 JAVA网关如何做线程池隔离 java线程隔离详解

JAVA网关如何做线程池隔离 java线程隔离详解

2023-07-12 19:19| 来源: 网络整理| 查看: 265

文章目录1. ThreadLocal的使用示例2. ThreadLocal的使用场景2.1 线程隔离的数据库连接与事务2.2 线程隔离的session会话3. ThreadLocal原理4. ThreadLocal与内存泄露4.1 Java语言将Entry设计为弱引用4.2 记得手动remove总结

在多线程并发环境中,要保证线程并发安全总体有2类方法。

使用锁,在访问资源时是互斥的、原子性的。这个锁可以是Synchronized方法 或 Lock。或者CAS方式的乐观锁。使用线程隔离的方法。变量在线程内部,在实际运行过程中只有这个线程可以读取。变量在线程外部定义,但是每个线程只能操作属于该线程的变量副本。即 ThreadLocal类型的变量。1. ThreadLocal的使用示例

定义了两个ThreadLocal类型的变量,线程t1设置的值,对于线程t2是不可见的。

public class ThreadLocalTest1 { private static ThreadLocal thl1 = new ThreadLocal(); private static ThreadLocal thl2 = new ThreadLocal(); public static void main(String[] args) { Thread t1 = new Thread(()->{ thl1.set("abc"); thl2.set(12); thl1.remove(); thl2.remove(); System.out.println(thl1.get()+","+ thl2.get()); }); Thread t2 = new Thread(()->{ System.out.println(thl1.get()+","+ thl2.get()); }); t1.start(); t2.start(); } }

运行结果:

JAVA网关如何做线程池隔离 java线程隔离详解_JAVA网关如何做线程池隔离

2. ThreadLocal的使用场景2.1 线程隔离的数据库连接与事务

定义一个数据库连接,每个线程拿到的数据库连接都是本线程对应的数据库连接。

public class ConnectionManager { private static final ThreadLocal dbConnectionLocal = new ThreadLocal() { @Override //初始化数据。 //延迟调用方法,在线程第一次调用get或set时才执行,并且只执行1次。默认返回null。 protected Connection initialValue() { try { return DriverManager.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return null; } }; public Connection getConnection() { return dbConnectionLocal.get(); } }2.2 线程隔离的session会话

在每个线程session会话都是本线程对应的session。

private static final ThreadLocal threadSession = new ThreadLocal(); public static Session getSession() { Session s = (Session) threadSession.get(); try { if (s == null) { s = getSessionFactory().openSession(); threadSession.set(s); } } catch (Exception ex) { } return s; }3. ThreadLocal原理Thread类内部定义了一个ThreadLocalMap 对象ThreadLocal.ThreadLocalMap threadLocals = null;当线程调用threadlocal对象的set(Object o)和get方法时,实际上是维护ThreadLocalMap对象。如果这个对象尚未初始化,则初始化set时,以threadlocal对象为key,o 为value。get时,以threadlocal对象为key取出value。举例说明: thl1.set("abc");thl2.set(12);两条命令会在线程内的ThreadLocalMap对象上插入两条记录,这两条记录的key分别是thl1,thl2。值分别是"abc",12。 thl1.get(); thl2.get();命令执行时,实际上会在当前线程内的ThreadLocalMap对象上,查找key为thl1、thl2的值。也就是说,每个线程内部其实都有一个专属的“记录”——ThreadLocalMap,当写入和读取时,都会以threadlocal对象的引用为key,去存储读取。4. ThreadLocal与内存泄露

内存泄露是指内存空间不可用,即使jvm进行垃圾回收也无法有效回收垃圾。

4.1 Java语言将Entry设计为弱引用

设想:当线程内对ThreadLocal对象使用方法完毕后,此时没有对象指向ThreadLocal对象,按理说这个对象可以被回收了。但是由于ThreadLocalMap里以key,value的形式存储了ThreadLocal对象。导致仍然有链接指向ThreadLocal对象,不能被回收。

因此,Java语言将Entry类设置为弱引用,当线程内对ThreadLocal对象使用方法完毕后,JVM可以在垃圾回收时,清除ThreadLocalMap内的无效Entry对象。

static class Entry extends WeakReference


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3