浅谈 Java “锁”
1、并发bug源头
1、可见性;电脑一般会有硬盘,内存,cpu,而硬盘和内存的速度相对cpu计算太慢,所有有cpu缓存(l1,l2,l3),并发操作时会去主存中拿值,拿到之后做操作再更新主存。
2、原子性;java代码看似一行,实际在字节码文件中都是多行的,并非原子操作,例如a++;
3、有序性;jvm编译代码时,为了性能优化,会改变代码执行顺序,即指令重排。
解决这些问题无非通过禁用缓存、禁止编译器指令重排、互斥等手段。
2、synchronized锁
1、作用于静态字段,静态方法,相当于锁类对象;
2、作用于非静态方法,非静态字段,相当于锁实例;
3、锁的粒度
1、需要注意某些线程安全的代码不需要加锁,需要细化,例如hashtable太粗,性能太差;
-细化举例,读写锁:读操作和写操作
2、粗化,有时候不需要太细,例如一个方法内调用了两个加锁方法,jvm会自动优化;
3、消除锁,jvm会自动优化某些不需要加锁的操作。