谈谈java的Collections.synchronized()

java中Collections.synchronized()的方法很好用~

有一次看到一个很优秀的同事写了以下一串代码,如下

 

private static volatile ConcurrentMap<String, Map<Integer, Set<String>>> all;
public void demo(){
  ... 
  Map<Integer, Set<String>> foo =Collections.synchronizedMap(new HashMap<Integer, Set<String>>()); //point 1
  ...
  Set<String> bar  = Collections.synchronizedSet(preIdSet);//point 2
  foo.put("ff",bar);
  ....
  all.put("bb",foo);//point 3
}


我本能的提出质疑,我说你见过哪个源码有这样写过?我对源码的阅读虽然不多,却也不能算是孤陋寡闻。这样的写法就是很奇怪。

 

我提出每个类方法中的变量都是安全的。怎么可能需要同步呢?

他的解释是代码会被放入在point 3的all全局变量中,这样的解释是合理的。

因为all是全局变量,你把point 1和point 2放入里面后,的确会面临被其它线程的修改。

 

最近看书,思想总是会飘来飘去。我想起了这件事,就再次思考。

首先对于all这个变量,它已经是线程安全的了,何必再继续对内部的每个变量再进行一次同步操作呢,这样只会浪费性能。

举个例子,要想保证all变量的线程安全,必须保证all里面的对象A不能被同时修改。

既然A对象已经被锁住不能同时修改了,何必继续对A对象内部的a加锁呢? 

修改a即是对A对象修改。所以它不可能被其他线程修改。

 

更正一下:

现在觉得以上想法是有问题的。

synchronized方法获得的对象 只保证对象的每个方法执行中是线程安全的。并不表示,方法结束后,它依然是线程安全的。

例如,线程安全的Map执行get(),会保证get中是线程安全的,但是get得到对象后,这个对象依然有可能被其他线程修改。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值