JVM线程安全
一、线程的调度方式
线程调度分为两种方式: 协同式调度和抢占式调度。
协同式调度:线程的执行时间由线程本身控制,线程将工作执行完之后,通知操作系统切换到其他线程上。缺点:时间不可控,就算出问题,也不会通知操作系统切换,容易阻塞。
抢占式调度:每个线程由操作系统来分配执行时间,调度。java的线程就是基于抢占式实现的。
通过线程优先级来控制执行时间。
二、线程的状态
(1)新建:创建后,未启动的线程。
(2)运行:此状态的线程,可能在执行,也有可能是在等待操作系统分配资源。
(3)无限期等待:不分配cpu时间,等待被唤醒。
(4)限期等待:不会分配cpu时间,不过无需等待其他线程唤醒,会自动唤醒。
(5)阻塞:等待资源。
(6)等待:等待唤醒。
(7)结束:已终止的线程。

三、线程安全
当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行其他任何协调操作,调用这个对象的行为都可以获取正确的结果,则这个对象是线程安全的。
java各种操作共享的数据分为以下5类:
(1)不可变
在java中,不可变的对象都是线程安全的。final修饰的对象,都是线程安全的。
(2)绝对线程安全
java中,标榜自己是线程安全的,往往都不是绝对线程安全的。
如Vector ,虽然add、get等方法都是用synchronized修饰,但并不是绝对线程安全带 。
(3)相对线程安全
保证对对象单独操作,是线程安全的。如Vector。
(4)线程兼容
线程兼容是指对象本身不是线程安全的,但是可以通过在调用端正确地使用同步手段来保证对象在并发环境中可以安全的使用。
(5)线程对立
线程对立是指无论调用端采取了何种措施,都无法在多线程环境中并发使用的代码。
3.1 synchronized
synchronized经过编译之后,是在同步块前后分别加上monitorenter和monitorexit这两个字节码指令。
(1)修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。相当于synchronized(A.class)
(2)修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
(3)修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象。锁的是this。也就是当前的对象。
(4)修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象。锁的是Class对象,也就是A.class.相当于全局锁,线程在该类中所有操作不能进行。
3.2 ReentrantLock
(1)等待可中断:
指拥有锁的线程长期不释放锁,正在等待的线程可以放弃等待。
(2)公平锁:
公平锁是指多个线程在等待同一个锁时,需要按照申请锁的时间顺序来获取到锁。
非公平锁是指多个线程在等待同一个锁时,获取到锁的概率是相同的。
ReentrantLock默认是非公平锁,但是可以构造出公平锁。
3.3 可重入代码
可以在代码执行的任意时刻中断它,转而去执行其他代码,在得到控制权之后,原来的程序不会出现任何错误,这个代码就为可重入代码。
可重入代码是线程安全的。
3.4 ThreadLocal
如果一段代码中所需要的数据必须与其他代码共享,那么最好将这些代码放在同一个线程中执行。这样,我们可以用ThreadLocal来实现数据在同一个线程中共享,而不会出现数据争用。
每个线程对象中,都有一个ThreadLocalMap对象,用来存放线程本地变量,变量只线程中的代码可见。其中最经典的一个应用就是,一个web端请求,对应一个服务器端线程,用以做上下文。spring 的数据库连接管理,hibernate的session管理。ThreadLocal模式解决的是同一线程中隶属于不同开发层次的数据共享问题,而不是在不同的开发层次中进行数据传递。
3.5 数据共享 OR 数据传递
ThreadLocal模式与synchronized关键字都是用于处理多线程并发访问变量的问题。只是两者处理问题的角度和思路不同。
(1)ThreadLocal是一个Java类,通过对当前线程(Thread)中的局部变量的操作来解决不同线程的变量访问的冲突问题。所以,ThreadLocal提供了线程安全的共享对象机制,每个线程(Thread)都拥有其副本。
(2)Java中的synchronized是一个保留字,它依靠JVM的锁机制来实现临界区的函数或者变量在访问中的原子性。在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。此时,被用作“锁机制”的变量是多个线程共享的。
同步机制采用了“以时间换空间”的方式,提供一份变量,让不同的线程排队访问。而ThreadLocal采用了“以空间换时间”的方式,为每一个线程都提供了一份变量的副本,从而实现同时访问而互不影响。
JVM线程安全的更多相关文章
- 【操作系统】二、JVM线程与Linux内核线程的映射
Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是 ...
- JVM线程状态,park, wait, sleep, interrupt, yeild 对比
---恢复内容开始--- JVM线程状态 NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED BLOCKED是等待获得对象锁 WAIT ...
- JVM线程与Linux内核线程的映射[转]
Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是 ...
- JVM线程状态Running、Sleeping、Wait、Park、Monitor
1,使用JVisualVM时,打开Threads监控,我们可以发现Java的线程状态有以下几种: 2,JVM线程状态: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_W ...
- 深入理解JVM线程模型
1. jvm内存模型在描述jvm线程模型之前,我们先深入的理解下,jvm内存模型.在jvm1.8之前,jvm的逻辑结构和物理结构是对应的.即Jvm在初始化的时候,会为堆(heap),栈(stack), ...
- 任务队列方案详解(一)JVM线程池
前言 我们都知道 web 服务的工作大多是接受 http 请求,并返回处理后的结果.服务器接受的每一个请求又可以看是一个任务.一般而言这些请求任务会根据请求的先后有序处理,如果请求任务的处理比较耗时, ...
- jvm 线程实现机制
简单记一下 实际上jvm 规范中并无做限制. 不同的jvm实现上存在一定差异.技术上的选择主要在 jvm的线程是如何和操作系统的线程对应的.有1:1 的线程实现模式,也有N:1的线程实现模式,更有M: ...
- 【转】java jvm 线程 与操作系统线程
原文链接:http://segmentfault.com/q/1010000000370403 Java的目标是要跨平台,而不同的操作系统(如类Unix和Windows)其任务调度机制有很大的不同,故 ...
- [Java Performance] JVM 线程调优
调整线程栈空间 当很缺少内存时,能够调整线程使用的内存. 每一个线程都有一个栈,用来记录该线程的调用栈信息.线程中的栈的默认空间是有OS和JVM的版本号决定的: OS 32-bit 64-bit Li ...
随机推荐
- js滚动条
/*滚动条在Y轴上的滚动距离*/function ScrollTop(){ var scrollTop = 0, bodyScrollTop = 0, documentScrollTop = 0; i ...
- UVALive 2147 Push!!(队列实现DP)
就我的理解来说这个题,本质上是一个DP题,不应该说是搜索,因为我的做法是把表格中所有的数据都找到,使用队列暴力来遍历出所有状态,因为题目中的数据范围小,所有耗时也小. 首先分析箱子是一个被动物体,人是 ...
- Python -- OOP高级 -- __slots__、@property
__slots__属性可以设置 允许被设置的属性 class Student: __slots__ = ("name", "age") >>> ...
- PowerDesigner 生成数据库字典(有图有真相,绝对自创非转载)
最近用pd做模型,生成数据字典时在网上找了很多,但是看的都很晕,说的不明白. 经过自己研究终于找到一个简单的方式,当然这只是简单的,大家举一反三去吧.辛苦弄的,求点赞!!! 先看效果图: 现在说一下步 ...
- HDU 5480 Conturbatio
区间求和不更新,开个数组记录一下前缀和就可以了 #include<cstdio> #include<cstring> #include<cmath> #includ ...
- UVA 11853 Paintball ——(dfs+圆交判定)
题意:给出一个1000*1000大小的矩阵,里面有若干圆,表示障碍物,现在要找出从左边到右边的一条通路,输出入口和出口的坐标,如果有多答案,输出y值最大的答案. 分析:从与上面相连的圆开始dfs,每次 ...
- 关于python的可变和不可变对象
在python中所有都是对象,在python中只有list和dict是可变对象,其他都是不可变对象. 具体参照:http://www.cnblogs.com/lovemo1314/archive/20 ...
- hdu_2688_Rotate(树状数组)
题目连接:hdu_2688_Rotate 题意:给你n数,(n<=3e6),有两个操作,Q为 当前有多少对数,满足严格递增,R l,r为旋转l,r这个区间的数 题解:求严格递增的顺序对我们可以反 ...
- SGU_390_Tickets(另类数位DP)
Tickets Time Limit : 1000/500ms (Java/Other) Memory Limit : 524288/262144K (Java/Other) Total Subm ...
- Linux 下安装配置 JDK1.7
目录[-] 1.下载JDK 2.解压安装 3.配置环境变量 4.配置默认JDK(一般情况下这一步都可以省略) 5.测试 1.下载JDK Linux操作系统是:Centos6.5-x64 目前最新的JD ...