随手记1

来源:互联网 发布:淘宝旺旺号怎么加好友 编辑:程序博客网 时间:2024/05/29 12:44

自己学习时零碎的知识点 用到哪个知识点了就记载下来,没有针对性,如果有看的朋友,就当垃圾拾宝吧,也许有你疏忽,或者有用的知识点


Math.random() 0~1之间的随机数

内部类不能使用静态方法

  • 内部类不能使用静态方法

Hashmap允许key和value为null,HashTable不允许key和value为null;HashTable是线程安全的


concurrentHashMap putifAbsent

synchronized(map){  if (map.get(key) == null){      return map.put(key, value);  } else{      return map.get(key);  }}

Map被分割成16个部分,并且由不同的锁控制。这意味着,同时最多可以有16个写线程操作Map。试想一下,由只能一个线程进入变成同时可由16个写线程同时进入(读线程几乎不受限制),性能的提升是显而易见的。但由于一些更新操作,如put(),remove(),putAll(),clear()只锁住操作的部分,所以在检索操作不能保证返回的是最新的结果。

另一个重要点是在迭代遍历CHM时,keySet返回的iterator是弱一致和fail-safe的,可能不会返回某些最近的改变,并且在遍历过程中,如果已经遍历的数组上的内容变化了,不会抛出ConcurrentModificationExceptoin的异常。

CHM默认的并发级别是16,但可以在创建CHM时通过构造函数改变。毫无疑问,并发级别代表着并发执行更新操作的数目,所以如果只有很少的线程会更新Map,那么建议设置一个低的并发级别。另外,CHM还使用了ReentrantLock来对segments加锁。
Java中ConcurrentHashMap putifAbsent方法的例子

很多时候我们希望在元素不存在时插入元素,我们一般会像下面那样写代码

synchronized(map){  if (map.get(key) == null){      return map.put(key, value);  } else{      return map.get(key);  }}

上面这段代码在HashMap和HashTable中是好用的,但在CHM中是有出错的风险的。这是因为CHM在put操作时并没有对整个Map加锁,所以一个线程正在put(k,v)的时候,另一个线程调用get(k)会得到null,这就会造成一个线程put的值会被另一个线程put的值所覆盖。当然,你可以将代码封装到synchronized代码块中,这样虽然线程安全了,但会使你的代码变成了单线程。CHM提供的putIfAbsent(key,value)方法原子性的实现了同样的功能,同时避免了上面的线程竞争的风险。
什么时候使用ConcurrentHashMap

CHM适用于读者数量超过写者时,当写者数量大于等于读者时,CHM的性能是低于Hashtable和synchronized Map的。这是因为当锁住了整个Map时,读操作要等待对同一部分执行写操作的线程结束。CHM适用于做cache,在程序启动时初始化,之后可以被多个请求线程访问。正如Javadoc说明的那样,CHM是HashTable一个很好的替代,但要记住,CHM的比HashTable的同步性稍弱。

CHM允许并发的读和线程安全的更新操作在执行写操作时,CHM只锁住部分的Map并发的更新是通过内部根据并发级别将Map分割成小部分实现的高的并发级别会造成时间和空间的浪费,低的并发级别在写线程多时会引起线程间的竞争CHM的所有操作都是线程安全CHM返回的迭代器是弱一致性,fail-safe并且不会抛出ConcurrentModificationException异常CHM不允许null的键值可以使用CHM代替HashTable,但要记住CHM不会锁住整个Map

以上就是Java中CHM的实现和使用场景


Map的put操作
  • hashtable, K,V均不能为null
  • HashMap K,V可为null, null 的hash返回0,所以多次Key为null会覆盖Value, 可以有多个不同的Key的Value为null。
  • ConcurrentHashMap, K,V均不能为null, ConcurrentHashMap中通过显示的null判断,对Key和Value均进行了验证

Map的get操作

  • Hashtable, K 不可为 null
  • HashMap,K可以为null
  • ConcurrentHashMap, K不能为null

ConcurrentHashMap V putIfAbsent(K key, V value) 如果key对应的value不存在,则put进去,返回null。否则不put,返回已存在的value。


Java关键字final、static使用总结

  • final类不能被继承,没有子类,final类中的方法默认是final的。
  • final方法不能被子类的方法覆盖,但可以被继承。
  • final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
  • final不能用于修饰构造方法。
  • 注意:父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。
  • 根据程序上下文环境,Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。

参考

  • http://lavasoft.blog.51cto.com/62575/18771/
  • http://blog.csdn.net/zero__007/article/details/49833819
原创粉丝点击