面试题:彻底理解ThreadLocal 索引的利弊 背1
、索引利弊 --整理
1、索引的好处
a、提高数据检索的效率,降低检索过程中必须要读取得数据量,降低数据库IO成本。
b、降低数据库的排序成本。因为索引就是对字段数据进行排序后存储的,如果待排序的字段与索引键字段一致,就在取出数据后不用再次排序了,因为通过索引取得的数据已满足排序要求。另外,分组操作是先排序后分组,所以索引同样可以省略分组的排序操作,降低内存与CPU资源的消耗。
2、索引的弊端
a、索引会增加 增、删、改操作所带来的IO量与调整索引的计算量。
b、索引要占用空间,随着数据量的不断增大,索引还会带来存储空间的消耗。
五、判断是否应该建索引的条件
1、较频繁的作为查询条件的字段应该创建索引
2、唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
3、增、删、改操作较多的数据库字段不适合建索引
所以,使用volatile变量能够保证:
- 每次
读取前必须先从主内存刷新最新的值。 - 每次
写入后必须立即同步回主内存当中。
也就是说,volatile关键字修饰的变量看到的随时是自己的最新值
早在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()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。
值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T> 泛型的类型就是副本变量的数据类型。API方法也相应进行了调整,新版本的API方法分别是void set(T value)、T get()以及T initialValue()。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。
Thread同步机制的比较
ThreadLocal和线程同步机制相比有什么优势呢?ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
由于ThreadLocal中可以持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,需要强制类型转换。但JDK 5.0通过泛型很好的解决了这个问题,在一定程度地简化ThreadLocal的使用,代码清单 9 2就使用了JDK 5.0新的ThreadLocal<T>版本。
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
spring使用ThreadLocal解决线程安全问题我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。
一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程
同一线程贯通三层这样你就可以根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有关联的对象引用到的都是同一个变量。
而总结的博文,总结一句话就是一个是锁机制进行时间换空间,一个是存储拷贝进行空间换时间。
面试题:彻底理解ThreadLocal 索引的利弊 背1的更多相关文章
- 深入理解ThreadLocal及其变种
ThreadLocal 定义 ThreadLocal很容易让人望文生义,想当然地认为是一个"本地线程". 其实,ThreadLocal并不是一个Thread,而是Thread的局部 ...
- 理解MySQL——索引与优化
转自:理解MySQL——索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存 ...
- 【Java】深入理解ThreadLocal
一.前言 要理解ThreadLocal,首先必须理解线程安全.线程可以看做是一个具有一定独立功能的处理过程,它是比进程更细度的单位.当程序以单线程运行的时候,我们不需要考虑线程安全.然而当一个进程中包 ...
- 理解ThreadLocal背后的概念
介绍 我之前在任何场合都没有使用过thread local,因此没有注意到它,直到最近用到它的时候. 前提信息 线程可以理解为一个单独的进程,它有自己的调用栈.在java中每一个线程都有一个调用栈或者 ...
- 深入理解mysql索引
深入理解mysql索引 1 深入理解索引 1.1 索引基础理论知识: 1.2 B+树索引 1.3 哈希索引 1.4 理解B+树.哈希索引结构及区别: 1.5 理解常见索引的基本概念:主键索引.唯一索引 ...
- 简单理解ThreadLocal原理和适用场景
https://blog.csdn.net/qq_36632687/article/details/79551828?utm_source=blogkpcl2 参考文章: 正确理解ThreadLoca ...
- Android 异步消息处理机制前篇(一):深入理解ThreadLocal
版权声明:本文出自汪磊的博客,转载请务必注明出处. ThreadLocal简介 ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获 ...
- 要想深入理解mysql索引?这16个点你必须要了解!
前言 MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度. 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQ ...
- 理解ThreadLocal(之二)
想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理.首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码 ...
随机推荐
- 51nod 1085 背包问题
在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数).求背包能够容纳的最大价值. 收起 输入 第1行,2个 ...
- HTML中id与name的用法
可以说几乎每个做过Web开发的人都问过,到底元素的ID和Name有什么区别阿?为什么有了ID还要有Name呢? 而同样我们也可以得到最经典的答案:ID就像是一个人的身份证号码,而Name就像是他的名字 ...
- LOJ#2351. 「JOI 2018 Final」毒蛇越狱
LOJ#2351. 「JOI 2018 Final」毒蛇越狱 https://loj.ac/problem/2351 分析: 首先有\(2^{|?|}\)的暴力非常好做. 观察到\(min(|1|,| ...
- gitlab Failed to register this runner. Perhaps you are having network problems runner 注册失败问题解决
1. 低版本安装地址 https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/v1.11.2/index.html 2. 使用 yum ...
- 常用DNS列表(电信、网通)
电信 DNS 列表 -- 共 32 条 (按拼音排序) 电信 A安徽 202.102.192.68 202.102.199.68 电信 A澳门 202.175.3.8 202.175.3.3 ...
- CF 504E Misha and LCP on Tree——后缀数组+树链剖分
题目:http://codeforces.com/contest/504/problem/E 树链剖分,把重链都接起来,且把每条重链的另一种方向的也都接上,在这个 2*n 的序列上跑后缀数组. 对于询 ...
- win7 安装过程中遇到的错误解决方法
win7 安装过程中遇到的错误解决方法 windows安装无法继续.若要安装windows 请单击 确定 重新启动计算机: 当 出现如上提示的时候,按下shift+f10 会打开命令窗口,进入到C:\ ...
- php sprintf()
在写php代码的时候,有时候会用到sprintf()这个函数,那么它是怎么用的呢? 学习源头: http://www.w3school.com.cn/php/func_string_sprintf.a ...
- zufeoj 花生(The Peanuts)
花生(The Peanuts) 时间限制: 1 Sec 内存限制: 128 MB提交: 3 解决: 2[提交][状态][讨论版] 题目描述 鲁宾逊先生和他的宠物猴,多多,非常喜欢花生.有一天,他们 ...
- 微信小程序只之全局存储
全局变量 app.globalData 本地缓存 wx.setStorageSync(KEY,DATA) wx.getStorageSync(KEY) wx.getStorageInfoSync wx ...