當前位置:編程學習大全網 - 腳本源碼 - disruptor怎麽設置多線程處理任務

disruptor怎麽設置多線程處理任務

壹個在線2k的遊戲,每秒鐘並發都嚇死人。傳統的hibernate直接插庫基本上是不可行的。我就壹步步推導出壹個無鎖的數據庫操作。

1. 並發中如何無鎖。

壹個很簡單的思路,把並發轉化成為單線程。Java的Disruptor就是壹個很好的例子。如果用java的concurrentCollection類去做,原理就是啟動壹個線程,跑壹個Queue,並發的時候,任務壓入Queue,線程輪訓讀取這個Queue,然後壹個個順序執行。

在這個設計模式下,任何並發都會變成了單線程操作,而且速度非常快。現在的node.js, 或者比較普通的ARPG服務端都是這個設計,“大循環”架構。

這樣,我們原來的系統就有了2個環境:並發環境 + ”大循環“環境

並發環境就是我們傳統的有鎖環境,性能低下。

”大循環“環境是我們使用Disruptor開辟出來的單線程無鎖環境,性能強大。

2. ”大循環“環境 中如何提升處理性能。

壹旦並發轉成單線程,那麽其中壹個線程壹旦出現性能問題,必然整個處理都會放慢。所以在單線程中的任何操作絕對不能涉及到IO處理。那數據庫操作怎麽辦?

增加緩存。這個思路很簡單,直接從內存讀取,必然會快。至於寫、更新操作,采用類似的思路,把操作提交給壹個Queue,然後單獨跑壹個Thread去壹個個獲取插庫。這樣保證了“大循環”中不涉及到IO操作。

問題再次出現:

如果我們的遊戲只有個大循環還容易解決,因為裏面提供了完美的同步無鎖。

但是實際上的遊戲環境是並發和“大循環”並存的,即上文的2種環境。那麽無論我們怎麽設計,必然會發現在緩存這塊上要出現鎖。

3. 並發與“大循環”如何***處,消除鎖?

我們知道如果在“大循環”中要避免鎖操作,那麽就用“異步”,把操作交給線程處理。結合這2個特點,我稍微改下數據庫架構。

原本的緩存層,必然會存在著鎖,例如:

public TableCache

{

private HashMap<String, Object> caches = new ConcurrentHashMap<String, Object>();

}

這個結構是必然的了,保證了在並發的環境下能夠準確的操作緩存。但是”大循環“卻不能直接操作這個緩存進行修改,所以必須啟動壹個線程去更新緩存,例如:

private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();

EXECUTOR.execute(new LatencyProcessor(logs));

class LatencyProcessor implements Runnable

{

public void run()

{

// 這裏可以任意的去修改內存數據。采用了異步。

}

}

OK,看起來很漂亮。但是又有個問題出現了。在高速存取的過程中,非常有可能緩存還沒有被更新,就被其他請求再次獲取,得到了舊的數據。

  • 上一篇:賭神秘笈之賭魔裏的春麗是誰扮演的
  • 下一篇:山河戀為什麽海蘭珠要設計害皇太極
  • copyright 2024編程學習大全網