平时写代码如何对synchronized优化

410 阅读1分钟

减少synchronized的范围

同步代码块中的代码尽量少,减少同步代码块中代码的执行时间,减少锁的竞争。

synchronized(Demo1.class) {
    System.out.println("qwer");
}
  1. synchronized中执行的时间短,单位时间内执行的线程就多一点,等待的线程就少一点。
  2. synchronized中执行的时间短,可能用轻量级锁或者自旋锁就能搞定,避免升级到重量级锁。

降低synchronized锁的粒度

将一个锁拆分为多个锁提高并发度

Hashtable

Hashtable hs = new Hashtable();
hs.put("a","b");
hs.put("c","d");

Hashtable 的 put、get、remove都是在方法上加synchronized,用的都是同一把锁。

ConcurrentHashMap

  1. ConcurrentHashMap的 get 方法没有加锁。
  2. put 方法中有通过cas和synchronized两种方式去添加节点,其中synchronized用的锁还不是同一把锁,用的是桶里面的第一个元素。添加元素的时候如果桶里面一个元素都没有,用cas去添加第一个元素,如果桶里面有元素需要往后加,会使用桶里面的第一个节点作为琐对象,也就意味着只会锁住一个桶里面的列表,不会影响其他线程对其他桶的增删改查操作。

尽量不要使用类名.class作为锁,降低锁的粒度,提高并发效率

读写分离

读取时不加锁,写入和删除时加锁

ConcurrentHashMap,CopyOnWriteArrayList和CopyOnWriteSet