private static int nextIndex(int i, int len) {
return ((i + 1 < len) ? i + 1 : 0);
}
private static int prevIndex(int i, int len) {
return ((i - 1 >= 0) ? i - 1 : len - 1);
}

ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
try {
threadLocal.set(new Session(1, "Misout的博客"));
// 其它业务逻辑
} finally {
threadLocal.remove();
}
//还记得Hibernate的session获取场景吗?
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
//获取Session
public static Session getCurrentSession(){
Session session = threadLocal.get();
//判断Session是否为空,如果为空,将创建一个session,并设置到本地线程变量中
try {
if(session ==null&&!session.isOpen()){
if(sessionFactory==null){
rbuildSessionFactory();// 创建Hibernate的SessionFactory
}else{
session = sessionFactory.openSession();
}
}
threadLocal.set(session);
} catch (Exception e) {
// TODO: handle exception
} return session;
}

public class MultiThreadDemo {
public static void main(String[] args) throws InterruptedException {
private int value = 0;
Thread increaseThread = new Thread(new Runnable() {
@Override
public void run() {
try {
value = 10;
Thread.sleep(10);
System.out.println("increase value: " + value);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}); Thread decreaseThread = new Thread(new Runnable() {
@Override
public void run() {
try {
value = -10;
Thread.sleep(10);
System.out.println("decrease value: " + value);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}); increaseThread.start();
decreaseThread.start();
}
}

public class SimpleImpl {  

    public static void main(String[] args) throws InterruptedException {
private Map<Long, Integer> cacheMap = new HashMap<>();
private int defaultValue = 0 ; Thread increaseThread = new Thread(new Runnable() {
@Override
public void run() {
long id = Thread.currentThread().getId();
cacheMap.put(id, 10);
Thread.sleep(10);
long id = Thread.currentThread().getId();
if (cacheMap.containsKey(id)) {
return cacheMap.get(id);
}
return defaultValue;
}
}); Thread decreaseThread = new Thread(new Runnable() {
@Override
public void run() {
long id = Thread.currentThread().getId();
cacheMap.put(id, -10);
Thread.sleep(10);
long id = Thread.currentThread().getId();
if (cacheMap.containsKey(id)) {
return cacheMap.get(id);
}
return defaultValue;
}
}); increaseThread.start();
decreaseThread.start();
}
}

public class SimpleImpl2 {

    public static class CommonThread extends Thread {
Map<Integer, Integer> cacheMap = new HashMap<>();
} public static class Number {
public void increase() throws InterruptedException {
Integer id = this.hashCode();
Map<Integer, Integer> cacheMap = (CommonThread) Thread.currentThread().cacheMap;
cacheMap.put(id, 10);
Thread.sleep(10);
return cacheMap.get(id);
} public void decrease() throws InterruptedException {
Integer id = this.hashCode();
Map<Integer, Integer> cacheMap = (CommonThread) Thread.currentThread().cacheMap;
cacheMap.put(id, -10);
Thread.sleep(10);
return cacheMap.get(id);
}
} public static void main(String[] args) throws InterruptedException {
final Number number = new Number();
Thread increaseThread = new CommonThread() {
@Override
public void run() {
number.increase();
}
}; Thread decreaseThread = new CommonThread() {
@Override
public void run() {
number.decrease();
}
};
increaseThread.start();
decreaseThread.start();
}
}

在上面的实现中,当线程消亡之后,线程中 cacheMap 也会被回收,它当中存放的副本变量(value)也会被全部回收,并且 cacheMap 是线程私有的,不会出现多个线程同时访问一个 cacheMap 的情况。在 Java 中,ThreadLocal 类的实现就是采用的这种思想,注意只是思想,实际的实现和上面的并不一样。

ThreadLocal源代码2的更多相关文章

  1. Java ThreadLocal 源代码分析

    Java ThreadLocal 之前在写SSM项目的时候使用过一个叫PageHelper的插件 可以自动完成分页而不用手动写SQL limit 用起来大概是这样的 最开始的时候觉得很困惑,因为直接使 ...

  2. 多线程之美2一ThreadLocal源代码分析

    目录结构 1.应用场景及作用 2.结构关系 2.1.三者关系类图 2.2.ThreadLocalMap结构图 2.3. 内存引用关系 2.4.存在内存泄漏原因 3.源码分析 3.1.重要代码片段 3. ...

  3. ThreadLocal源代码3

    public class ThreadLocal1<T> { //当创建了一个 ThreadLocal 的实例后,它的散列值就已经确定了, //threadLocal实例的hashCode ...

  4. ThreadLocal源代码1

    public class ThreadLocalTrxt { static ThreadLocal<Object> x1 = new ThreadLocal<Object>() ...

  5. 另一鲜为人知的单例写法-ThreadLocal

    另一鲜为人知的单例写法-ThreadLocal 源代码范例 当我阅读FocusFinder和Choreographer的时候,我发现这两类的单例实现和我们寻经常使用双重检查锁非常不一样.而是用来一个T ...

  6. java ThreadLocal(应用场景及使用方式及原理)

    尽管ThreadLocal与并发问题相关,可是很多程序猿只将它作为一种用于"方便传參"的工具,胖哥觉得这或许并非ThreadLocal设计的目的,它本身是为线程安全和某些特定场景的 ...

  7. ThreadLocal分析

    我们再介绍一个在多线程环境中经常使用的类ThreadLocal,它是java为解决多线程程序的并发问题提供了一种新的方向,使用这个ThreadLocal类可以帮助开发者很简单地编写出简洁的程序,并且是 ...

  8. ThreadLocal深入理解与内存泄露分析

    ThreadLocal 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本.所以每个线程都能够独立地改变自己的副本.而不会影响其他线程所相应的副本. ...

  9. 深入理解线程本地变量ThreadLocal

    ThreadLocal理解: 假设在多线程并发环境中.一个可变对象涉及到共享与竞争,那么该可变对象就一定会涉及到线程间同步操作,这是多线程并发问题. 否则该可变对象将作为线程私有对象,可通过Threa ...

随机推荐

  1. MySQL利用LOCATE,CONCAT查询

    SELECT * FROM table t WHERE 1=1 AND LOCATE(#{searchParams},CONCAT(t.account,IFNULL(t.id,''),IFNULL(t ...

  2. java语言评价--java帝国

    “陛下您想想,我们有很多宝贝,” IO大臣根本不理线程大臣, 继续侃侃而谈:“ 比如IoC, AOP,反射.动态代理.泛型.注解.JDBC.JMS...... 还有我们引以为豪的JVM.这些东西,那些 ...

  3. 常用方法 DataTable转换为Entitys

    备注:摘自网上 有附地址 public static List<T> DataTableToEntities<T>(this DataTable dt) where T : c ...

  4. 洛谷P2068 统计和题解

    题目描述 给定一个长度为n(n<=100000),初始值都为0的序列,x(x<=10000)次的修改某些位置上的数字,每次加上一个数,然后提出y (y<=10000)个问题,求每段区 ...

  5. LOJ3097 SNOI2019 通信 题解

    题目链接 费用流,当建边需要依靠位置和权值两个偏序关系时,可以用cdq分治优化建边. 代码: #include<bits/stdc++.h> using namespace std; #d ...

  6. uniapp 组件传参

    父组件 <v-sub @returnDate=returnDate :backGround=backGround></v-sub> import vSub from " ...

  7. Golang 接口

    1 接口是什么 Golang中没有像Python.Java拥有类和对象的概念,其封装对象或说明对象是通过接口来实现的.比如谁能够实现什么样的功能,便能够将其抽象化封装. 接口定义了一组方法(抽象方法集 ...

  8. Spring Boot进阶系列一

    笔者最近在总结一个 Spring Boot实战系列,以方便将来查找和公司内部培训用途. 1.Springboot从哪里来 SpringBoot是由Pivotal团队在2013年开始研发.2014年4月 ...

  9. 华为云ARM64服务器试用

    公司同事弄了个华为云的ARM64服务器,让我帮忙部署我们的服务,所以先试用了一下. 总体感觉还行,使用的CentOS系统,yum也能用,epel源也可以用.但是SCL软件集用不了. uname -a ...

  10. 理解Spring定时任务@Scheduled的两个属性fixedRate和fixedDelay

    fixedRate和fixedDelay都是表示任务执行的间隔时间 fixedRate和fixedDelay的区别:fixedDelay非常好理解,它的间隔时间是根据上次的任务结束的时候开始计时的.比 ...