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. java内部类的本质

    连接与通信,作为桥接中间件存在. 内部类和主体类可以无障碍通信: 1.通过继承连接实现: 2.通过接口连接通信: 形式: 1.命名空间: 2.运行上下文: 其它: 信息隐藏是次要功能. 内部类 Jav ...

  2. Colorful events

  3. 洛谷p2672推销员题解

    日常扯废话: 话说题解里的思路都写得真的是很奈斯啊 但是 代码看不懂确实让人头疼(可能是我太弱了) 就像题解里的第一篇题解代码简洁但是属实看不明白 趁着学姐刚给我讲了知识还热乎赶紧给泥萌说说哈 正文: ...

  4. 修改git log中的Date格式

    默认的git log查看日志显示的格式如下: Date:   Thu Aug 16 17:44:32 2018 +0800 说实话,真不太喜欢这种日期格式还是换成数值比较舒服一点.git bash中使 ...

  5. JS回调函数怎么写的?

    相信每个做前端的同学都用过太多太多的回调函数, 接下来就看看回调函数是怎么来的. 这玩意儿也没那么神秘,直接看代码: 声明函数的时候,把回调函数用作参数,并且在函数内调用它 function getD ...

  6. gethostname、gethostbyname

    gethostname():返回本地主机的标准主机名 原型: #include<unistd.h> int gethostname(char *name, size_t len); 参数说 ...

  7. linux 搭建局域网YUM源仓库服务器

    yum简介 Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从指定的服 ...

  8. 声源定位之2精读《sound localization based on phase difference enhancement using deep neuarl networks》

    2.1.1 题目与摘要 1.为什么要增强IPD? The phase differences between the discrete Fourier transform (DFT) coeffici ...

  9. dateTime格式转换

    select Convert(varchar(8),GETDATE(),112) Select replace(CONVERT(varchar(8), GETDATE(), 108),':','')

  10. linux , nginx: 封禁IP的办法【转】

    今天,我们的一台服务器出了问题: 被若干IP地址访问某个接口,该接口会发送短信. 所以,我们可以做两件事: 1. nginx的层面封IP .  2  linux server的层面封IP 先看ngin ...