java lazy_Java性能优化要点之五: 队列与lazySet
Java性能優化要點之五: 隊列與lazySet
隊列需要對正確的應用使用好正確的隊列Queue,否則會產生性能問題,隊列分生產者和消費者,或者發布者訂閱者,它們之間有一對多和多對多以及多對一等關系。
SPSC:一個Producer :一個Consumer
SPMC:一個Producer :多個Consumer
MPSC:多個Producer :多個Consumer
MPMC:多個Producer :多個Consumer
記住:在JDK中所有并發的隊列Queue都是MPMC。JAQ-InABox是一個提高了性能的Queue實現。
Atomic*.lazySet(…)
根據單寫原理,JDK的AtomicLong.lazySet等方法是便宜的最好性能,成本低便宜的volatile 寫總是受大家歡迎,前提是只有一個寫入者,也就是一個Producer。
以AtomicReference的lazySet為例子,其代碼如下:
public final void lazySet(V newValue) {
unsafe.putOrderedObject(this, valueOffset, newValue);
}
lazySet是使用Unsafe.putOrderedObject方法,這個方法在對低延遲代碼是很有用的,它能夠實現非堵塞的寫入,這些寫入不會被Java的JIT重新排序指令(instruction reordering),這樣它使用快速的存儲-存儲(store-store) barrier, 而不是較慢的存儲-加載(store-load) barrier, 后者總是用在volatile的寫操作上,這種性能提升是有代價的,雖然便宜,也就是寫后結果并不會被其他線程看到,甚至是自己的線程,通常是幾納秒后被其他線程看到,這個時間比較短,所以代價可以忍受。
類似Unsafe.putOrderedObject還有unsafe.putOrderedLong等方法,unsafe.putOrderedLong比使用 volatile long要快3倍左右。.
在DDD中有值對象概念,值對象的特點是不可變的,而我們經常要修改的狀態是可變的,結合lazySet和值對象我們可以編寫并發性很好的可變狀態修改。
比如:Forum論壇有一個論壇狀態ForumState,論壇狀態主要是當前最新的帖子等信息,每次有新貼發布時,會更新論壇狀態,我們將ForumState設計成一個值對象,一旦有新的帖子發布,就創建一個新的對象 ForumState,然后替換掉舊的狀態,這種替換動作可以使用AtomicLong.lazySet來完成。
public class Forum extends ForumModel {
private volatile AtomicReference forumState;
public ForumState getForumState() {
try {
return forumState.get();
} finally {
}
}
public void setForumState(ForumState forumState) {
this.forumState.lazySet(forumState);
}
..
}
總結
以上是生活随笔為你收集整理的java lazy_Java性能优化要点之五: 队列与lazySet的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java ipv6校验_JS及java验
- 下一篇: java 内存屏障类型_Java内存模型