@sun.misc.Contended避免僞共享(false sharing)
轉載自:http://www.myexception.cn/program/1630142.html
Java8中使用sun.misc.Contended註解來避免僞共享(false sharing)。關於僞共享這個概念,可以先參照http://ifeve.com/falsesharing/
僞共享的例子:
如果有兩個VolatileLong對象,會被load到同一個緩存行裏面,如果一個線程要修改對象1,另一個線程同時要修改對象2,此時就要面對僞共享問題(core1對緩存行中對象1的修改,導致core2中同一緩存行失效,即緩存的對象2需要重新load)。
jdk6中的解決辦法:
上面的方式也就是long padding來避免僞共享,使用無關數據來填充緩存行,使得兩個VolatileLong對象不會load到同一個緩存行裏面。無鎖併發框架Disruptor正是採用的這種方式。
long padding的解決辦法不怎麼優雅,並且在jdk7某個版本以後能會優化掉long padding,詳細參考http://ifeve.com/false-sharing-java-7/。但是java8已經給出了官方的解決辦法,就是sun.misc.Contended註解。
這裏,JVM就不會將被Contended註解的兩個VolatileLong對象load到同一個緩存行裏面。要注意的是user classpath使用此註解默認是無效的,需要在jvm啓動時設置-XX:-RestrictContended。(不太理解。。。經測試,自己應用程序的sun.misc.Contended註解的類需要-XX:-RestrictContended才能生效,是不是對jdk源碼中的sun.misc.Contended不需要上述註解就可以生效了?)
jdk8中有很多地方已經使用了sun.misc.Contended:
java/util/concurrent/ConcurrentHashMap.java
java/util/concurrent/Exchanger.java
Java8中使用sun.misc.Contended註解來避免僞共享(false sharing)。關於僞共享這個概念,可以先參照http://ifeve.com/falsesharing/
僞共享的例子:
如果有兩個VolatileLong對象,會被load到同一個緩存行裏面,如果一個線程要修改對象1,另一個線程同時要修改對象2,此時就要面對僞共享問題(core1對緩存行中對象1的修改,導致core2中同一緩存行失效,即緩存的對象2需要重新load)。
jdk6中的解決辦法:
上面的方式也就是long padding來避免僞共享,使用無關數據來填充緩存行,使得兩個VolatileLong對象不會load到同一個緩存行裏面。無鎖併發框架Disruptor正是採用的這種方式。
long padding的解決辦法不怎麼優雅,並且在jdk7某個版本以後能會優化掉long padding,詳細參考http://ifeve.com/false-sharing-java-7/。但是java8已經給出了官方的解決辦法,就是sun.misc.Contended註解。
這裏,JVM就不會將被Contended註解的兩個VolatileLong對象load到同一個緩存行裏面。要注意的是user classpath使用此註解默認是無效的,需要在jvm啓動時設置-XX:-RestrictContended。(不太理解。。。經測試,自己應用程序的sun.misc.Contended註解的類需要-XX:-RestrictContended才能生效,是不是對jdk源碼中的sun.misc.Contended不需要上述註解就可以生效了?)
jdk8中有很多地方已經使用了sun.misc.Contended:
java/util/concurrent/ConcurrentHashMap.java
java/util/concurrent/Exchanger.java
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.