threadlocal

ThreadLocal是什么?保证线程安全

和自甴很熟 提交于 2019-12-29 03:05:19
早在JDK 1.2的版本中就提供 Java .lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。   当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。   从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。   所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。 ThreadLocal的接口方法 ThreadLocal类接口很简单,只有4个方法,我们先来了解一下: void set(Object value)设置当前线程的线程局部变量的值。 public Object get()该方法返回当前线程所对应的线程局部变量。 public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。 protected Object initialValue

一文带你了解那些不为人知的Java线程技巧与用法

别等时光非礼了梦想. 提交于 2019-12-28 02:41:01
萝卜白菜各有所爱。像我就喜欢Java。学无止境,这也是我喜欢它的一个原因。日常工作中你所用到的工具,通常都有些你从来没有了解过的东西,比方说某个方法或者是一些有趣的用法。比如说线程。没错,就是线程。或者确切说是Thread这个类。当我们在构建高可扩展性系统的时候,通常会面临各种各样的并发编程的问题,不过我们现在所要讲的可能会略有不同。 从本文中你将会看到线程提供的一些不太常用的方法及技术。不管你是初学者还是高级用户或者是Java专家,希望都能看一下哪些是你已经知道的,而哪些是刚了解的。如果你认为关于线程还有什么值得分享给大家的,希望能在下面积极回复。那我们就先开始吧。 初学者 1.线程名 程序中的每个线程都有一个名字,创建线程的时候会给它分配一个简单的Java字符串来作为线程名。默认的名字是”Thread-0″, “Thread-1″, “Thread-2″等等。现在有趣的事情来了——Thread提供了两种方式来设置线程名: 线程构造函数,下面是最简单的一个实现: class SuchThread extends Thread { Public void run() { System.out.println ("Hi Mom! " + getName()); } } SuchThread wow = new SuchThread(“much-name”); 线程名setter方法:

Java单例模式探究

我们两清 提交于 2019-12-27 08:27:56
作为对象的创建模式 [GOF95] , 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。由定义可以总结出单例模式的要点有三个:一是单例类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。 在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个 Printer Spooler ,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。 虽然从类图上看,单例模式是最简单的设计模式之一,但是真正正确地使用单例模式却不是那么简单的事。 首先看一个经典的单例实现。 public class Singleton { private static Singleton uniqueInstance = null ; private Singleton() { // Exists only to defeat instantiation. } public static Singleton getInstance() { if ( uniqueInstance ==

一文带你彻底搞懂ThreadLocal

两盒软妹~` 提交于 2019-12-27 04:05:31
前言 共享变量一直是并发中的老大难问题,每个线程都对它有操作权,所以线程之间的同步很关键,锁也就应运而生。这里换一个思路,是否可以把共享变量私有化?即每个线程都拥有一份共享变量的本地副本,每个线程对应一个副本,同时对共享变量的操作也改为对属于自己的副本的操作,这样每个线程处理自己的本地变量,形成数据隔离。事实上这就是ThreadLocal了。 就线程同步而言,锁可以认为是时间换空间,ThreadLocal可以认为是空间换时间,其实个人觉得这么描述有点强行往同步靠的意思,专业的人干专业的事,同步这个还是就老老实实交给锁吧。 ThreadLocal最适合的是变量在线程间隔离而在方法或类间共享的场景。 ThreadLocal的应用场景 ThreadLocal在Spring中事务的应用 我们可能每天都在使用Spring写dao写service,真的是一个非常爽的框架.我们能用这么爽是因为Spring在底层把脏活儿累活儿全干了。在一个Service中我们可能要写很多个dao,如果多个dao都用不同的JDBC连接,很费时费力费资源不说,事务性就得不到保证了,因为我们知道事务需要在一个连接内才能得以实现。事务对应着连接,所以如果我们每个线程对应一个连接,也就能保证我们在一个service中很爽的叨叨叨了,Spring底层正是使用ThreadLocal对连接进行了封装,可劲儿叨吧你就

多线程与Android线程性能优化

假装没事ソ 提交于 2019-12-26 17:17:38
目录 多线程与Android线程性能优化 基础概念 CPU核心数和线程数的关系 CPU时间片轮转机制 什么是进程和线程 澄清并行和并发 高并发编程的意义、好处和注意事项 认识Java里的线程 线程的启动与中止 对Java里的线程再多一点点认识 深入理解run()和start() 其他的线程方法 线程间的共享和协作 线程间的协作 ThreadLocal 显式锁 Lock接口和synchronized的比较 Lock接口和核心方法 可重入锁ReentrantLock、所谓锁的公平和非公平 读写锁ReentrantReadWriteLock Condition接口 多线程与Android线程性能优化 基础概念 CPU核心数和线程数的关系 多核心:也指单芯片多处理器( Chip Multiprocessors,简称CMP),CMP是由美国斯坦福大学提出的,其思想是将大规模并行处理器中的SMP(对称多处理器)集成到同一芯片内,各个处理器并行执行不同的进程。这种依靠多个CPU同时并行地运行程序是实现超高速计算的一个重要方向,称为并行处理 多线程: Simultaneous Multithreading.简称SMT.SMT可通过复制处理器上的结构状态,让同一个处理器上的多个线程同步执行并共享处理器的执行资源可最大限度地实现宽发射、乱序的超标量处理,提高处理器运算部件的利用率,缓和由于数据相关或

Java并发编程:深入剖析ThreadLocal

 ̄綄美尐妖づ 提交于 2019-12-25 02:12:39
Java并发编程:深入剖析ThreadLocal   想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理。首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码分析了其实现原理和使用需要注意的地方,最后给出了两个应用场景。   以下是本文目录大纲:   一.对ThreadLocal的理解   二.深入解析ThreadLocal类   三.ThreadLocal的应用场景   若有不正之处请多多谅解,并欢迎批评指正。   请尊重作者劳动成果,转载请标明原文链接:    http://www.cnblogs.com/dolphin0520/p/3920407.html 一.对ThreadLocal的理解   ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多。可能很多朋友都知道ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。   这句话从字面上看起来很容易理解,但是真正理解并不是那么容易。   我们还是先来看一个例子: class ConnectionManager { private static Connection connect = null; public static Connection

Java并发--线程安全策略

喜夏-厌秋 提交于 2019-12-24 01:18:51
1 不可变对象 用不可变对象保证线程安全,是相当于不让线程并发,逃避了并发。 不可变对象就是指一个类的实例化对象不可变。比如String类的实例 主要方法有:   将类声明为final   将所有成员声明为 private   对变量不提供 set 方法,将所有可变成员声明为 final,只能赋值一次,通过构造器初始化所有成员,进行深度拷贝   在 get 方法中不直接返回对象本身,而是克隆对象,并返回对象的拷贝。 final关键字 一个类的private方法会隐式的指定为final方法 final还可以修饰方法的参数,表示该参数在方法中使用时不可以修改。 这里需要注意的是,final修饰的引用数据类型中其内部数据还是可以被修改的,比如一个final修饰的map,有数据<1,3>,可以被修改为<1,2>,所以并不是线程安全的。需要进行解决。 Collections.unmodifiableXXX 系列方法,可以解决上述问题 ,它可以将输入的引用对象变为不可变对象,内部也是不可变的 Guava:ImmutableXXX系列方法也可以达到相同的效果 2 线程封闭 把对象封装到一个线程中,只有这一个线程可以看到这个对象,那么这个对象就不用考虑线程安全问题。 下面用例子演示ThreadLocal的使用: 参考博客: 面试官再问你 ThreadLocal,你就这样“怼”回去!   

正确理解ThreadLocal

点点圈 提交于 2019-12-24 01:07:03
首先,ThreadLocal 不是用来解决共享对象的多线程訪问问题的,普通情况下。通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其它线程是不须要訪问的,也訪问不到的。各个线程中訪问的是不同的对象。 另外,说ThreadLocal使得各线程可以保持各自独立的一个对象,并非通过ThreadLocal.set()来实现的,而是通过每一个线程中的new 对象 的操作来创建的对象,每一个线程创建一个。不是什么对象的拷贝或副本。通过ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每一个线程都有这样一个map,运行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,ThreadLocal实例是作为map的key来使用的。 假设ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发訪问问题。 以下来看一个hibernate中典型的ThreadLocal的应用: [java] view plain copy private static final ThreadLocal threadSession = new ThreadLocal(); public

threadLocal 和 线程池 问题记录

孤街浪徒 提交于 2019-12-21 13:43:21
threadLocal 和 线程池 问题记录 问题 在web应用中,获取用户的身份后,使用filter将身份信息采用putIfAbsent的形式放在了 threadLocal 中。循环请求servlet,发现用户身份没有变化。 解析 只有当ThreadLocal的生命周期受限于Task的生命周期时,在Thread Pool的Thread里使用ThreadLocal才有意义。 在线程池的线程中不应该使用ThreadLocal在任务之间传递值。 ThreadLocal的生命周期不等于一次request请求的生命周期,每个request请求的响应是tomcat从线程池中分配的线程,线程会被下个请求复用。所以请求结束后必须删除线程本地变量。 在使用ThreadLocal的时候管理它的创建、销毁,那么就可以用。 来源: CSDN 作者: 是小黄鸡不是小黄鸭 链接: https://blog.csdn.net/weixin_41004986/article/details/103642444

多线程---线程间的通信

左心房为你撑大大i 提交于 2019-12-18 13:53:04
1 . wait() 方法使当前执行代码的线程进行等待,将当前线程置入"预执行队列",并且在wait()方法所在处停止执行,直到接到通知或者中断。 在调用wait之前,线程必须获得该对象的对象级别锁,即 只能在同步方法或者同步代码块中才能调用wait方法 。 调用wait()方法后当前线程自动释放锁 。在从wait()返回之前,线程与其他线程竞争重新获得锁。 2 . notify() 用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则由线程规划器随机选出其中一个呈wait状态的线程对其发出notify, 并使它获取该对象的对象锁,值得注意的是在执行notify方法后当前线程不会马上释放该对象锁,呈wait状态的线程也不能马上获得该对象锁,要等到执行notify方法的线程将线程执行完,也就是退出synchronized代码块后,当前线程才会释放锁,而呈wait状态的线程才可以获取该对象锁。当第一个获得了该对象锁的线程运行完毕之后它会释放掉该对象锁,此时如果对象没有再次使用notify方法,即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,还会阻塞在wait状态,直到这个对象发出一个notify或者notifyAll. notify方法也要在同步方法或者同步代码块中才能调用,线程也必须获得该对象的对象级别锁 3 .