<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          多線程知識點(樂觀鎖/悲觀鎖)整理

          共 1862字,需瀏覽 4分鐘

           ·

          2021-04-02 10:12

          多線程:

          多線程其實就是指線程在同一時間在cpu上同時進行。具體分為兩種模式:一種是指多條線程在同一個cpu上分段時間運行,其實就是并行的意思。一種是多條線程在cpu上同時運行的,其實就是并發(fā)的意思。

          多線程的問題

          多線程主要的問是,在多條線程運行情況下,會出現(xiàn)以下情況:

          1.多個線程同時競爭同一個資源的問題,導(dǎo)致線程出現(xiàn)安全問題

          2.線程之間的調(diào)用資源互相等待,如下圖:


          那么問題來了,為了避免線程安全問題,我們應(yīng)該如何避免線程安全的問題了:

          1.進行加鎖操作:就是對多個線程要都是使用的資源進行加鎖操作,加鎖的操作有三個個思想方向:

          悲觀鎖:所謂的悲觀鎖,其實就是一種悲觀的心態(tài),也就像是你是對什么事情都報悲觀的看法,認為所有的事 , 不好的影響是一定會發(fā)生的,基于這個觀點。所有在對多線程中要使用的公共資源,你也認為發(fā)生線程不安全的問題是一定要發(fā)生的,那就先把她加一把鎖上,這樣讓每一來調(diào)用資源的線程,都先看看資源是否在使用、如果已經(jīng)被其中一個線程使用,其他線程就等待。

          樂觀鎖:與悲觀的看法不一樣的是,你認為發(fā)生不好事情的幾率是很小的,所以基于這個觀點,在多線程使用公共資源的時候,你認為大多時候,線程使用都是安全的,那么我們在多條線程來調(diào)用資源的時候,就不需要來想悲觀鎖一樣來加把鎖上,而是直接就調(diào)用。只是看看調(diào)用的時候,資源的狀態(tài)如何就行。其中一種很經(jīng)典的思路cas(比較替換)就是樂觀鎖的實現(xiàn)。


          cas 中的邏輯就是,在線程進入調(diào)用資源的時候,需要獲取到資源的值,這個值最好是具有唯一性的,如時間戳,版本號等,然后在要對資源的數(shù)據(jù)進行修改的時候,在吧前面獲取的原本的資源值與當(dāng)前資源的值進行比較。如果相等,就說明資源在當(dāng)前線程運行時。沒有進行過改變的操作(要防止ABA問題)。就對資源進行值的變更。如果不相等,就說明已經(jīng)進行了相關(guān)的變更操作。次線程需要重新獲取資源的新值,在來比較。現(xiàn)在的java的atomic包中的類,都是實現(xiàn)了cas的樂觀鎖的。

          ABA問題

          ABA的問題就是cas思想中一個經(jīng)典的問題。其出現(xiàn)的的情況大致如何。說先有兩條線程A,B 來獲取到資料的值為A。然后線程A先對資源進行了操作,把資料的值改為了B。就在線程A執(zhí)行完,線程B執(zhí)行前。來了條線程C,其獲取到資源的值為B,然后通過對比比較之后,把資源的值B改為了A。那么當(dāng)前的資源的值就是A,在線程C執(zhí)行完之后,線程B在來執(zhí)行對比比較。發(fā)現(xiàn)資源的值是A,與線程B最先獲取的值是相等的,然后線程B就執(zhí)行了對資源值得修改。其實在線程B執(zhí)行之前,資源的值是發(fā)生了變化的A變成了B,再從B變成了A。所以線程B不應(yīng)該執(zhí)行,而是應(yīng)該進入循環(huán),在來一次獲取值,對比值。這也是前面我問什么提醒在cas的時候,要把標(biāo)識值用友唯一性的東西來做的原因

          前面說的加鎖的悲觀鎖和樂觀鎖,但是悲觀鎖的效率低,不利于高并發(fā)的情況。樂觀鎖的效率高,但是對內(nèi)存的消耗也大,也是一個不足。那么有沒有既考慮到效率,有考慮到內(nèi)存的問題了。其實還真有一種鎖。讀寫鎖。

          讀寫鎖:

          首先要說明,不是所有的讀寫鎖都滿足既考慮到效率,有考慮到內(nèi)存的話,我說的是讀寫鎖中采用共享模式,獨占模式相結(jié)合的,如:ReentrantReadWriteLock類,其就是能夠多線程讀取資料,寫線程的時候是加了鎖的。但是這要先介紹一種思路,AQS,就是同步器的概念。在AQS的,是會有個虛擬先進先出的隊列來裝插入隊列中的線程。而且里面還是雙向鏈表結(jié)構(gòu)。然后其有有個狀態(tài)來表示公共資源。而線程對公共資源的使用方式分為兩種。一種是獨享占用,一種共享,其中獨享占用又分為公平競爭和非公平競爭。公平競爭就是先到先得的意思,指先進入隊列的線程優(yōu)先獲取資源;而非公平競爭是指隊列中的線程自由競爭資源,誰先獲取到資源,誰就使用。

          2.其實保證線程安全,也可以不用加鎖的模式。就比如spirng中ioc中生成的對象默認的是單例模式,但是我們可以設(shè)置為prototype多例模式;而且針對我們還可以用TherdLocal這個類,來對線程中公共使用的對象復(fù)制,然后使用,只有記得指使用完之后,將復(fù)制的對象刪除,避免內(nèi)存溢出的問題就行。

          3.還有比如利用redis中的setnx 來保證線程的安全,也是可以的。


          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩A√中文字幕在线 | 91人妻人人操 | 天天摸天天射 | 亚洲欧美一区二区三区久本道 | 国产精品久久久久久久久久久久久久久久久 |