最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2013年11月19日 09:27:39   作者:  
一個(gè)在線2k的游戲,每秒鐘并發(fā)都嚇?biāo)廊恕鹘y(tǒng)的hibernate直接插庫(kù)基本上是不可行的。我就一步步推導(dǎo)出一個(gè)無(wú)鎖的數(shù)據(jù)庫(kù)操作,詳情看下文

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

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

問(wèn)題再次出現(xiàn):
如果我們的游戲只有個(gè)大循環(huán)還容易解決,因?yàn)槔锩嫣峁┝送昝赖耐綗o(wú)鎖。
但是實(shí)際上的游戲環(huán)境是并發(fā)和“大循環(huán)”并存的,即上文的2種環(huán)境。那么無(wú)論我們?cè)趺丛O(shè)計(jì),必然會(huì)發(fā)現(xiàn)在緩存這塊上要出現(xiàn)鎖。

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

復(fù)制代碼 代碼如下:

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

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

復(fù)制代碼 代碼如下:

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

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

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

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

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

相關(guān)文章

  • Java反射機(jī)制原理、Class獲取方式以及應(yīng)用場(chǎng)景詳解

    Java反射機(jī)制原理、Class獲取方式以及應(yīng)用場(chǎng)景詳解

    反射機(jī)制是JAVA的核心知識(shí)點(diǎn)之一,大多數(shù)框架的實(shí)現(xiàn)原理就是利用了反射機(jī)制,掌握反射機(jī)制會(huì)使你學(xué)習(xí)框架更加輕松高效,這篇文章主要給大家介紹了關(guān)于Java反射機(jī)制原理、Class獲取方式以及應(yīng)用場(chǎng)景的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • 剖析Java中在Collection集合中使用contains和remove為什么要重寫(xiě)equals

    剖析Java中在Collection集合中使用contains和remove為什么要重寫(xiě)equals

    這篇文章主要介紹了Collection集合的contains和remove方法詳解remove以及相關(guān)的經(jīng)驗(yàn)技巧,通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Java服務(wù)器處理圖片上傳的方法

    Java服務(wù)器處理圖片上傳的方法

    這篇文章主要為大家詳細(xì)介紹了Java服務(wù)器處理圖片上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 快速了解Maven

    快速了解Maven

    這篇文章主要介紹了快速了解Maven,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • java使用ajax完成上傳文件

    java使用ajax完成上傳文件

    這篇文章主要為大家詳細(xì)介紹了java使用ajax完成上傳文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入

    Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)excel大數(shù)據(jù)量導(dǎo)入,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • springboot整合quartz實(shí)現(xiàn)定時(shí)任務(wù)示例

    springboot整合quartz實(shí)現(xiàn)定時(shí)任務(wù)示例

    spring支持多種定時(shí)任務(wù)的實(shí)現(xiàn)。我們來(lái)介紹下使用spring的定時(shí)器和使用quartz定時(shí)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • 淺談基于SpringBoot實(shí)現(xiàn)一個(gè)簡(jiǎn)單的權(quán)限控制注解

    淺談基于SpringBoot實(shí)現(xiàn)一個(gè)簡(jiǎn)單的權(quán)限控制注解

    這篇文章主要介紹了基于SpringBoot實(shí)現(xiàn)一個(gè)簡(jiǎn)單的權(quán)限控制注解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • java 可重啟線程及線程池類(lèi)的設(shè)計(jì)(詳解)

    java 可重啟線程及線程池類(lèi)的設(shè)計(jì)(詳解)

    下面小編就為大家?guī)?lái)一篇java 可重啟線程及線程池類(lèi)的設(shè)計(jì)(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • Java獲取請(qǐng)求頭、參數(shù)、路徑方式

    Java獲取請(qǐng)求頭、參數(shù)、路徑方式

    這篇文章主要介紹了Java獲取請(qǐng)求頭、參數(shù)、路徑方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03

最新評(píng)論

尚义县| 衡山县| 兴安县| 罗城| 嫩江县| 宜黄县| 正阳县| 湛江市| 花垣县| 德兴市| 中阳县| 英超| 永昌县| 建水县| 孟津县| 抚松县| 汽车| 奇台县| 长沙县| 华安县| 麦盖提县| 秦安县| 公安县| 南开区| 安塞县| 光山县| 元氏县| 德庆县| 宣武区| 和平县| 洛浦县| 淅川县| 遵化市| 永兴县| 旬邑县| 竹山县| 宕昌县| 榆树市| 应城市| 彰化市| 北流市|