欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用JAVA實現(xiàn)高并發(fā)無鎖數(shù)據(jù)庫操作步驟分享

 更新時間:2013年11月19日 09:27:39   作者:  
一個在線2k的游戲,每秒鐘并發(fā)都嚇死人。傳統(tǒng)的hibernate直接插庫基本上是不可行的。我就一步步推導出一個無鎖的數(shù)據(jù)庫操作,詳情看下文

1. 并發(fā)中如何無鎖。
一個很簡單的思路,把并發(fā)轉(zhuǎn)化成為單線程。Java的Disruptor就是一個很好的例子。如果用java的concurrentCollection類去做,原理就是啟動一個線程,跑一個Queue,并發(fā)的時候,任務壓入Queue,線程輪訓讀取這個Queue,然后一個個順序執(zhí)行。
在這個設計模式下,任何并發(fā)都會變成了單線程操作,而且速度非常快?,F(xiàn)在的node.js, 或者比較普通的ARPG服務端都是這個設計,“大循環(huán)”架構。
這樣,我們原來的系統(tǒng)就有了2個環(huán)境:并發(fā)環(huán)境 + ”大循環(huán)“環(huán)境
并發(fā)環(huán)境就是我們傳統(tǒng)的有鎖環(huán)境,性能低下。
"大循環(huán)"環(huán)境是我們使用Disruptor開辟出來的單線程無鎖環(huán)境,性能強大。

2. ”大循環(huán)“環(huán)境 中如何提升處理性能。
一旦并發(fā)轉(zhuǎn)成單線程,那么其中一個線程一旦出現(xiàn)性能問題,必然整個處理都會放慢。所以在單線程中的任何操作絕對不能涉及到IO處理。那數(shù)據(jù)庫操作怎么辦?
增加緩存。這個思路很簡單,直接從內(nèi)存讀取,必然會快。至于寫、更新操作,采用類似的思路,把操作提交給一個Queue,然后單獨跑一個Thread去一個個獲取插庫。這樣保證了“大循環(huán)”中不涉及到IO操作。

問題再次出現(xiàn):
如果我們的游戲只有個大循環(huán)還容易解決,因為里面提供了完美的同步無鎖。
但是實際上的游戲環(huán)境是并發(fā)和“大循環(huán)”并存的,即上文的2種環(huán)境。那么無論我們怎么設計,必然會發(fā)現(xiàn)在緩存這塊上要出現(xiàn)鎖。

3. 并發(fā)與“大循環(huán)”如何共處,消除鎖?
我們知道如果在“大循環(huán)”中要避免鎖操作,那么就用“異步”,把操作交給線程處理。結合這2個特點,我稍微改下數(shù)據(jù)庫架構。
原本的緩存層,必然會存在著鎖,例如:

復制代碼 代碼如下:

public TableCache
{
  private HashMap<String, Object> caches = new ConcurrentHashMap<String, Object>();
}

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

復制代碼 代碼如下:

private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
EXECUTOR.execute(new LatencyProcessor(logs));

class LatencyProcessor implements Runnable
{
  public void run()
  { 
    // 這里可以任意的去修改內(nèi)存數(shù)據(jù)。采用了異步。
  }
}

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

4. 如何保證并發(fā)環(huán)境下緩存數(shù)據(jù)的唯一正確?
我們知道,如果只有讀操作,沒有寫操作,那么這個行為是不需要加鎖的。
我使用這個技巧,在緩存的上層,再加一層緩存,成為”一級緩存“,原來的就自然成為”二級緩存“。有點像CPU了對不?
一級緩存只能被”大循環(huán)“修改,但是可以被并發(fā)、”大循環(huán)“同時獲取,所以是不需要鎖的。
當發(fā)生數(shù)據(jù)庫變動,分2種情況:
1)并發(fā)環(huán)境下的數(shù)據(jù)庫變動,我們是允許有鎖的存在,所以直接操作二級緩存,沒有問題。
2)”大循環(huán)“環(huán)境下數(shù)據(jù)庫變動,首先我們把變動數(shù)據(jù)存儲在一級緩存,然后交給異步修正二級緩存,修正后刪除一級緩存。
這樣,無論在哪個環(huán)境下讀取數(shù)據(jù),首先判斷一級緩存,沒有再判斷二級緩存。
這個架構就保證了內(nèi)存數(shù)據(jù)的絕對準確。
而且重要的是:我們有了一個高效的無鎖空間,去實現(xiàn)我們?nèi)我獾臉I(yè)務邏輯。

最后,還有一些小技巧提升性能。
1. 既然我們的數(shù)據(jù)庫操作已經(jīng)被異步處理,那么某個時間,需要插庫的數(shù)據(jù)可能很多,通過對表、主鍵、操作類型的排序,我們可以刪除一些無效操作。例如:
a)同一個表同一個主鍵的多次UPdate,取最后一次。
b)同一個表同一個主鍵,只要出現(xiàn)Delete,前面所有操作無效。
2. 既然我們要對操作排序,必然會存在一個根據(jù)時間排序,如何保證無鎖呢?使用
private final static AtomicLong _seq = new AtomicLong(0);
即可保證無鎖又全局唯一自增,作為時間序列。

相關文章

  • Servlet注解之@WebInitParam多個InitParam的使用

    Servlet注解之@WebInitParam多個InitParam的使用

    這篇文章主要介紹了Servlet注解之@WebInitParam多個InitParam的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Spring Cloud項目前后端分離跨域的操作

    Spring Cloud項目前后端分離跨域的操作

    這篇文章主要介紹了Spring Cloud項目前后端分離跨域的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Java異常處理中同時有finally和return語句的執(zhí)行問題

    Java異常處理中同時有finally和return語句的執(zhí)行問題

    這篇文章主要介紹了Java異常處理中同時有finally和return語句的執(zhí)行問題,首先確定的是一般finally語句都會被執(zhí)行...然后,需要的朋友可以參考下
    2015-11-11
  • JavaMail入門教程之接收郵件(4)

    JavaMail入門教程之接收郵件(4)

    這篇文章主要為大家詳細介紹了JavaMail入門教程之接收郵件的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Java注釋代碼執(zhí)行方法解析

    Java注釋代碼執(zhí)行方法解析

    這篇文章主要介紹了Java注釋代碼執(zhí)行方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Java線程中synchronized的用法與原理解析

    Java線程中synchronized的用法與原理解析

    這篇文章主要介紹了Java線程中synchronized的用法與原理解析,只要有線程,就會有并發(fā)的現(xiàn)象,也同時會產(chǎn)生數(shù)據(jù)不一致,那么對于需要使用同一個數(shù)據(jù)的兩個線程,就會產(chǎn)生沖突,那么就引出了鎖的概念,本篇會針對性的說下synchronized這個關鍵字,需要的朋友可以參考下
    2024-01-01
  • Hibernate Validation自定義注解校驗的實現(xiàn)

    Hibernate Validation自定義注解校驗的實現(xiàn)

    這篇文章主要介紹了Hibernate Validation自定義注解校驗的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • SpringBoot整合RabbitMQ的5種模式的注解綁定詳解

    SpringBoot整合RabbitMQ的5種模式的注解綁定詳解

    這篇文章主要介紹了SpringBoot整合RabbitMQ的5種模式的注解綁定詳解,RabbitMQ 是一個消息中間件,它接收消息并且轉(zhuǎn)發(fā),是"消費-生產(chǎn)者模型"的一個典型的代表,一端往消息隊列中不斷的寫入消息,而另一端則可以讀取或者訂閱隊列中的消息,需要的朋友可以參考下
    2024-01-01
  • Mybatis中SqlSession接口中selectList方法詳解

    Mybatis中SqlSession接口中selectList方法詳解

    這篇文章主要給大家介紹了關于Mybatis中SqlSession接口中selectList方法的相關資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2023-03-03
  • MyBatis高級映射和查詢緩存

    MyBatis高級映射和查詢緩存

    這篇文章主要介紹了MyBatis高級映射和查詢緩存的相關資料,需要的朋友可以參考下
    2016-06-06

最新評論