用synchronized对方法进行同步,还真不一定线程安全,来看个简单的例子
上面的代码运行出来的结果:
看到没,并不是2000000,那么为什么f1和f3方法都用了synchronized关键字,然而并没有达到我们需要的结果呢?这需要从synchronized的原理开始讲起。
synchronized关键字有下面三种用法:
修饰实例方法:对当前实例加锁,进入方法需要获得当前实例的锁
修饰静态方法:对当前类对象加锁,进入静态方法需要获得当前类对象的锁
修饰代码块:对指定对象进行加锁,进入代码块需要获得指定对象的锁
那么上面三种方式有什么区别呢?这需要先理解下synchronized的底层语义。java中的同步是基于进入和退出管程(Moniter)对象来实现的,无论是显式同步(有明确的monitorenter和monitorexit指令,即同步代码块)还是隐式同步(同步方法,方法调用指令读取运行时常量池中的方法的ACC_SYNCHRONIZED标志来隐式实现的)。
先看下基于对象实现的,需要了解下java对象。在JVM中,对象在内存中的区域分成三部分:对象头,实例变量,填充数据。
实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。
填充数据:由于虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐,这点了解即可。
对象头:是实现synchronized锁对象的基础。synchronized使用的锁对象是存储在Java对象头里的,其主要结构是由Mark Word 和 Class Metadata Address 组成。
其中Mark Word在默认情况下存储着对象的HashCode、分代年龄、锁标记位等以下是32位JVM的Mark Word默认存储结构
synchronized的对象锁,锁标识位为10,其中指针指向的是monitor对象(也称为管程或监视器锁)的起始地址。每个对象都存在着一个 monitor 与之关联,对象与其 monitor 之间的关系有存在多种实现方式,如monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成,但当一个 monitor 被某个线程持有后,它便处于锁定状态。
了解了对象头,我们就可以知道为什么上面的代码虽然都使用了synchronized修饰,但是还是有线程安全问题,因为静态方法和实例方法锁的对象是不一致的(Monitor不是同一个),所以导致最终没有达到预期效果。
相关推荐
你还在用synchronized?线程安全相关知识深入剖析
Synchronized锁在Spring事务管理下,导致线程不安全。
synchronized与单例的线程安全问题,博客地址:https://www.jianshu.com/p/486ed9c8662a
【ASP.NET编程知识】实例解析Java中的synchronized关键字与线程安全问题.docx
1.什么是线程安全性(what) 2.如何分辨一个类是否线程安全?(HOW) 3.为什么hashmap不安全 why 3.1 插入HashMap.put 3.1.1 HashMap 在扩容的时候 3.2 HashMap 在删除数据的时候 0.背景 经常会看到说HashMap是线程...
针对synchronized同步代码块中,使用的锁进行一些测试。如果以某类的成员变量所谓锁,可以让线程同步吗?答案是可以的。 测试代码展示了线程同步和线程执行顺序 的区别。
线程安全,使用synchronized关键字
栈的线程安全问题 的解决代码 push pop synchronized THread
Java中的synchronized:同步方法与线程安全
如果一个资源(变量,对象,文件,数据库)可以同时被很多线程使用会出现数据不一致问题,也是我们说的线程安全问题。这样的资源被称为共享资源或临界区。 举个例子: 一个共享变量m,现在有两个线程同时对...
java多线程安全性基础介绍 线程安全 正确性 什么是线程安全性 原子性 竞态条件 i++ 读i ++ 值写回i 可见性 JMM 由于cpu和内存加载速度的差距,在两者之间增加了多级缓存导致,内存并不能直接对cpu可见。 ...
文章目录多线程安全问题和锁线程在jvm中的特点锁的出现synchronized 关键字-监视器锁monitor lock死锁的产生和避免 什么是线程安全问题? 当多个线程同时操作同一个数据是,可能会出现数据不一样的情况,这就是线程...
视频讲解: 1、为什么我们要了解线程安全?因为多线程无处不在。 2、线程-我们分布式,高性能应用的基础。...7、用了synchronized就高枕无忧了?那死锁是怎么回事? 8、死锁只是线程安全问题的一角,来了解更多。
NoHttp核心架构之多线程通信、线程安全、线程同步;synchronized锁,Lock锁;具体讲解请移步博客:http://blog.csdn.net/yanzhenjie1003/article/details/50992468
实例解析Java中的synchronized关键字与线程平安问题_.docx
首先要清楚的是synchronized锁住的不是代码而是对象,因而在编写相关的代码块时要注意线程同步安全问题,下面就来以实例解析Java中的synchronized关键字与线程安全问题
可以使用Java中的同步机制,如使用synchronized关键字或者使用线程安全的集合类来保证多线程操作的安全性。 实现步骤: 创建一个下载管理器类,用于管理下载任务和线程池。 在下载管理器中实现多线程下载的逻辑,...
NoHttp核心架构之多线程通信、线程安全、线程同步;synchronized锁,Lock锁;具体讲解请移步:http://blog.csdn.net/yanzhenjie1003/article/details/50992468
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。