[置顶] 深入探析Java线程锁机制
今天在iteye上提了一个关于++操作和线程安全的问题,一位朋友的回答一言点醒梦中人,至此我对Java线程锁有了更加深刻的认识。在这里也做个总结供大家参考。
先看几段代码吧!
代码一:
- public class TestMultiThread2 implements Runnable{
- private static Object o = new Object();
- private static Integer si = 0;
- private static AtomicInteger flag = new AtomicInteger();
- @Override
- public void run() {
- for(int k=0;k<2000000;k++){
- synchronized(si){
- si++;
- }
- }
- flag.incrementAndGet();
- }
- public static void main(String[] args) throws InterruptedException{
- TestMultiThread2 t1 = new TestMultiThread2();
- TestMultiThread2 t2 = new TestMultiThread2();
- ExecutorService exec1 = Executors.newCachedThreadPool();
- ExecutorService exec2 = Executors.newCachedThreadPool();
- exec1.execute(t1);
- exec2.execute(t2);
- while(true){
- if(flag.intValue()==2){
- System.out.println("si>>>>>"+si);
- break;
- }
- Thread.sleep(50);
- }
- }
- }
为了方便看,重复的就不插入了,从代码二到代码四只插入run()方法中的代码,其他地方都一样
代码二:
- public void run() {
- for(int k=0;k<2000000;k++){
- synchronized(o){
- si++;
- }
- }
- flag.incrementAndGet();
- }
代码三:
- public void run() {
- for(int k=0;k<2000000;k++){
- synchronized(o){
- si++;
- o = new Object();
- }
- }
- flag.incrementAndGet();
- }
代码四:
- public void run() {
- for(int k=0;k<2000000;k++){
- synchronized(o){
- si++;
- Object temp = o;
- o = new Object();
- o = temp;
- }
- }
- flag.incrementAndGet();
- }
有了这四段代码我想问题大概可以说明白了,这里说一下输出吧。
代码一:<4000000
代码二:=4000000
代码三:<4000000
代码四:<4000000(PS:这个结果非常接近4000000)
这里说明一下我测试中碰到的问题,代码四一直没有跑出我想要的结果,主要是开始我设的循环次数太少,其实这里如果要这个现象更加明显一些可以在中间多new 几个Object 如下面的代码五,这样现象就比较明显了.
代码五:
- public void run() {
- for(int k=0;k<2000000;k++){
- synchronized(o){
- si++;
- Object temp = o;
- for(int m=0;m<10;m++){
- o = new Object();
- }
- o = temp;
- }
- }
- flag.incrementAndGet();
- }
为什么会出现上面的现象:
代码一:当si做++操作后(可以直接看字节码,这里不贴了),在putstatic之前有几步操作,就是我们常说的非原子操作,而这时候si已经不是原来的对象了,这样锁对另外一个线程来说就失效了,我想代码三和代码四就是最好的佐证,代码四更有说服力。当时因为没有出现预想的情况困惑了挺久。
其实这里用字节码来解释还不是很严谨,最好的当然直接是汇编代码
如有什么问题还希望各位读者指正。
zhuanzi:http://blog.csdn.net/luohuacanyue/article/details/8307617
[置顶] 深入探析Java线程锁机制的更多相关文章
- Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁
(1)synchronized 是互斥锁: (2)ReentrantLock 顾名思义 :可重入锁 (3)ReadWriteLock :读写锁 读写锁特点: a)多个读者可以同时进行读b)写者必须互斥 ...
- JAVA线程锁-读写锁
JAVA线程锁,除Lock的传统锁,又有两种特殊锁,叫读写锁ReadWriteLock 其中多个读锁不互斥,读锁和写锁互斥,写锁和写锁互斥 例子: /** * java线程锁分为读写锁 ReadWri ...
- Java线程锁一个简单Lock
/** * @author * * Lock 是java.util.concurrent.locks下提供的java线程锁,作用跟synchronized类似, * 单是比它更加面向对象,两个线程执行 ...
- Java线程锁&分布式锁的理解及应用
了解Java线程锁之前,先理解线程和进程的定义.进程是操作系统分配资源(CPU)的基本单位,线程是CPU执行的基本单位,一个进程可拥有多个线程,同进程间的多个线程共享分配给进程的资源.比如启动JVM时 ...
- 工作常用4种Java线程锁的特点,性能比较、使用场景
多线程的缘由 在出现了进程之后,操作系统的性能得到了大大的提升.虽然进程的出现解决了操作系统的并发问题,但是人们仍然不满足,人们逐渐对实时性有了要求. 使用多线程的理由之一是和进程相比,它是一种非常花 ...
- Java的锁机制--synchronsized关键字
引言 高并发环境下,多线程可能需要同时访问一个资源,并交替执行非原子性的操作,很容易出现最终结果与期望值相违背的情况,或者直接引发程序错误. 举个简单示例,存在一个初始静态变量count=0,两个线程 ...
- Java线程锁,synchronized、wait、notify详解
(原) JAVA多线程这一块有点绕,特别是对于锁,对锁机制理解不清的话,程序出现了问题也很难找到原因,在此记录一下线程的执行以及各种锁. 1.JAVA中,每个对象有且只有一把锁(lock),也叫监视器 ...
- lesson3:java的锁机制原理和分析
jdk1.5之前,我们对代码加锁(实际是对象加锁),都是采用Synchronized关键字来处理,jdk1.5及以后的版本中,并发编程大师Doug Lea在concurrrent包中提供了Lock机制 ...
- java的锁机制
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在Java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...
随机推荐
- Qt实现探测当前有没有网络连接(Wi-Fi)——QNetworkConfigurationManager.isOnline()
1.只需要探测当前有没有连上Wi-Fi(不用获取网络状态),可以调用<QNetworkConfigurationManager>类. QNetworkConfigurationManage ...
- USB2.0学习笔记连载(十九):EZ-USB TRM手册重要部分介绍
TRM手册中给出了所有的寄存器配置,在 slave fifo模式或者 GPIF模式等,所以对于用到的各种寄存器配置需要查看此手册,当然还可以配合着应用手册<AN61345>. ...
- 对微软Microsoft Dynamics CRM 的认识
MS CRM的认识 技术层面: MS CRM使用了当前最为流行的Web Service作为数据交互的手段,这给我们的二次开发和系统级的集成带来了无可比拟的方便性.易用性.我们不用关心如何去访问CRM数 ...
- 针对程序集 'SqlServerTime' 的 ALTER ASSEMBLY 失败,因为程序集 'SqlServerTime' 未获授权(PERMISSION_SET = EXTERNAL_ACCESS)
错误: 针对程序集 'SqlServerTime' 的 ALTER ASSEMBLY 失败,因为程序集 'SqlServerTime' 未获授权(PERMISSION_SET = EXTERNAL_A ...
- CentOS6.8下安装MySQL5.6
一:卸载旧版本 使用下面的命令检查是否安装有MySQL Server rpm -qa | grep mysql 有的话通过下面的命令来卸载掉 rpm -e mysql //普通删除模式 rpm -e ...
- FusionCancer-人类癌症相关的融合基因的数据库
RNA-seq 测序可以用于融合基因的发现,在过去的十几年里,RNA-seq 测序数据不断增加,发现的融合基因的数据也不断增加: FusionCancer 是一个人类癌症相关的融合基因的数据库,利用N ...
- 一篇关于apache commons类库的详解[转]
1.1. 开篇 在Java的世界,有很多(成千上万)开源的框架,有成功的,也有不那么成功的,有声名显赫的,也有默默无闻的.在我看来,成功而默默无闻的那些框架值得我们格外的尊敬和关注,Jakarta C ...
- shiro实现动态权限管理
用到shiro框架实现权限控制时,根据实际要求,权限在数据库增删改后都要把权限过滤链变化实时更新到服务器中. 1.配置文件里配置的filterchains都是静态的,但实际开发中更多的是从数据库中动态 ...
- 第一个jquery程序
<html> <head></head> <script type="text/javascript" src="jquery- ...
- 软件设计模式之代理模式(JAVA)
貌似停笔了近半个月了,实在不该啊,新的一年,时刻让自己归零. Back To Zero,就从这篇文章拉开今年的序幕吧. 这篇文章准备介绍下有关代理模式的基本概念和静态代理.动态代理的优缺点及使用方法( ...