测试一个案例 jdk1.6版本之前;
public class Test {
public static void main(String[] args) throws InterruptedException {
A a = new A();
long start = System.currentTimeMillis();
Thread t1 = new Thread(() ->{
for (int i = 0; i<10000000; i++){
a.increase();
}
});
t1.start();
for (int i = 0; i<10000000; i++){
a.increase();
}
t1.join();
long end = System.currentTimeMillis();
System.out.println(String.format("%sms",end-start));
System.out.println(a.getNum());
}
}
public class A {
int num = 0;
public int getNum() {
return num;
}
public void increase(){
synchronized(this){
num++;
}
}
}
打印结果是如下,正确结果应该是20000000
由于多线程并发问题,导致结果异常,
加入Synchronized如下:
加入锁有结果正确,但是执行时间明显加长很多,将近增加了7倍;
Synchronized 底层原理:
通过AtomicInteger效率会大大的增加:
public class A {
int num = 0;
AtomicInteger atomicInteger = new AtomicInteger();
public int getNum() {
return atomicInteger.get();
}
public void increase(){
/*synchronized(this){
num++;
}*/
atomicInteger.incrementAndGet();
}
}
输出如下:
CAS底层是compareAndSwapInt通过先比较再替换的原理实现,整个操作是原子操作,
CAS指令执行时,当且仅当旧值与预期值A相等时,才可以把值修改为B,否则就什么都不做。
②整个比较并替换的操作是一个原子操作,通过硬件指令支持
再底层就是C++和汇编语言实现的,汇编原理:通过lock cmpxchgq这2个执行解决的,
在硬件级别通过汇编语言还是添加锁:先添加缓存行锁,如果数据超过64字节,就会添加总线程锁,
jdk1.6版本之后:Synchronized 执行流程级别,根据不同线程执行不同级别的锁,一个线程是和多个线程等
一个对象的组成结构
对象头组成结构
打印对象内部一个组成结构的依赖包
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>