亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談同步監(jiān)視器之同步代碼塊、同步方法

 更新時間:2017年08月24日 09:44:55   投稿:jingxian  
下面小編就為大家?guī)硪黄獪\談同步監(jiān)視器之同步代碼塊、同步方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

如果有多個線程訪問共享資源,可能會出現(xiàn)當(dāng)一個線程沒有處理完業(yè)務(wù),然后另一個線程進(jìn)入,從而導(dǎo)致共享資源出現(xiàn)不安全的情況。

日常例子:銀行取錢,A和B有擁有同一個銀行賬戶,A用存折在柜臺取錢,B在取款機(jī)取錢。取錢有兩個關(guān)鍵步驟:

(1)判斷賬戶里的錢的余額是否大于所取錢數(shù)

(2)如果大于所取錢數(shù),則賬戶最終所剩余額 = 余額 - 所取錢數(shù)。

如果沒有線程同步的情況下,我們假設(shè)這一種情況,這個共同的賬戶里共1000元。

(1)A B同時去取600元,A所在線程執(zhí)行到上面的第一個步驟,判斷所取錢數(shù)小于現(xiàn)有余額,CPU時間片用完。

(2)這時B進(jìn)來到第一個步驟,同樣是執(zhí)行判斷,因?yàn)锳只執(zhí)行完第一步驟,沒有執(zhí)行減法,這時現(xiàn)有余額還是1000元。

(3)由于在CPU分配的時間里他接著完成了減法操作。這時賬戶余額為1000 - 600 = 400。成功取出600元。

(4)最后A接著之前執(zhí)行的步驟,去做減法操作, 賬戶余額為 -200 = 400 - 600。

到這里,我只想說為什么,是什么銀行可以允許你這么做, 當(dāng)然,除非銀行是你家開的。

總之銀行不可能讓這種情況發(fā)生,所以我們的偉大先賢們就想到線程同步,其實(shí)很簡單,你也能想到。如果讓這兩個步驟同時完成,不可分開,問題也就迎刃而解。

下面就說到在JAVA中同步代碼的實(shí)現(xiàn):

涉及概念:同步監(jiān)視器,是一個普通的java對象,同一個同步監(jiān)視器如果一個線程拿到,則其他線程就沒有辦法拿到。好像是一個房門里只有唯一的一把鑰匙, 不能復(fù)制。如果一個人拿著它進(jìn)入房門,其他人只能在外面等候。等他出來你獲得了它,你才能進(jìn)入房間。

下面的代碼如果沒有做線程同步操作(同步代碼塊、同步方法、同步鎖)結(jié)果是如下:

Thread-1------判斷所取錢數(shù)是否大于余額------
Thread-0------判斷所取錢數(shù)是否大于余額------
Thread-0======做減法操作,取出現(xiàn)金======
Thread-1======做減法操作,取出現(xiàn)金======

很顯然線程1的那兩步?jīng)]有同時完成。

下面的幾種方法可以實(shí)現(xiàn)兩步同時完成。

1、同步代碼塊:

public class ThreadTest {

  public static void main(String[] args){
Thread t1 = new Thread1(); //線程1
Thread t2 = new Thread1();//線程2
t1.start();
t2.start();
  }
}

class Thread1 extends Thread{

  @Override
  public void run() {
super.run();
try {

  BeTested b = new BeTested(); // 這地方,因?yàn)檫@個例子中同步監(jiān)視器 obj 是線程共享的,兩個線程用兩個不同的對象,也沒有關(guān)系,不影響結(jié)果。
  b.beTested(this);
} catch (InterruptedException e) {
  e.printStackTrace();
}
  }
}

class BeTested {
  static Object obj = new Object();;
  public void beTested(Thread t) throws InterruptedException{
synchronized (obj) { // obj 為同步監(jiān)視器
  System.out.println(t.getName() + "------判斷所取錢數(shù)是否大于余額------");
  t.sleep(1000); // 如果沒有同步這樣能理明顯地看到這兩步驟不能在一個線程,同一個時間片里執(zhí)行完成。
  System.out.println(t.getName() + "======做減法操作,取出現(xiàn)金======");
}
  }
}

執(zhí)行結(jié)果如下:

Thread-0------判斷所取錢數(shù)是否大于余額------
Thread-0======做減法操作,取出現(xiàn)金======
Thread-1------判斷所取錢數(shù)是否大于余額------
Thread-1======做減法操作,取出現(xiàn)金======

注意:同步監(jiān)視器對象的選用很關(guān)鍵。要選擇線程共享的對象,比如上面例子的 obj, 它是static修飾的才行,如果沒有static修飾,則是使用不同的同步監(jiān)視器(不是同一個對象),相當(dāng)于是兩把鑰匙。

 ?。ㄈ绻鹢bj = "aaaa" 沒有static修飾也可以實(shí)現(xiàn)同步,那是因?yàn)檫@個obj引用的常量池里的同一個string對象,強(qiáng)烈不推薦使用)

2、同步方法(非靜態(tài)方法)

把上面的那兩類改成如下,main方法所在類不變。

class Thread1 extends Thread{

  static BeTested b = new BeTested(); // 在這種方法中,這里必須是同個對象(static修飾),下文會詳細(xì)說明
  @Override
  public void run() {
super.run();
try {
  b.beTested(this);
} catch (InterruptedException e) {
  e.printStackTrace();
}
  }
}

class BeTested {
  static Object obj = new Object();;
  public synchronized void beTested(Thread t) throws InterruptedException{
  System.out.println(t.getName() + "------判斷所取錢數(shù)是否大于余額------");
  t.sleep(1000); 
  System.out.println(t.getName() + "======做減法操作,取出現(xiàn)金======");
  }
}

執(zhí)行結(jié)果如下:

Thread-0------判斷所取錢數(shù)是否大于余額------
Thread-0======做減法操作,取出現(xiàn)金======
Thread-1------判斷所取錢數(shù)是否大于余額------
Thread-1======做減法操作,取出現(xiàn)金======

注意:因?yàn)橥椒椒ㄖ校玫耐奖O(jiān)視器不能指定,默認(rèn)使用的調(diào)用該方法的對象,也就是this。所以 Thread1 類中相對于示例1中同步代碼塊中修改的部分, 也是要static修飾。也就是說要使用同一個對象。

3、同步方法(靜態(tài)方法)

把上面的那兩類改成如下,main方法所在類不變。

class Thread1 extends Thread{

  @Override
  public void run() {
super.run();
try {
  BeTested b = new BeTested(); // 這里每個線程使用不同的對象。
  b.beTested(this);
} catch (InterruptedException e) {
  e.printStackTrace();
}
  }
}

class BeTested {
  static Object obj = new Object();;
  public static synchronized void beTested(Thread t) throws InterruptedException{
  System.out.println(t.getName() + "------判斷所取錢數(shù)是否大于余額------");
  t.sleep(1000); 
  System.out.println(t.getName() + "======做減法操作,取出現(xiàn)金======");
  }
}

執(zhí)行結(jié)果如下:

Thread-0------判斷所取錢數(shù)是否大于余額------
Thread-0======做減法操作,取出現(xiàn)金======
Thread-1------判斷所取錢數(shù)是否大于余額------
Thread-1======做減法操作,取出現(xiàn)金======

注意:因?yàn)橥届o態(tài)方法中,同步監(jiān)視器是這個類而不是這個類的對象。所以Thread1 類中相對于示例2中同步代碼塊中修改的部分,不須要用static修飾,不是同一個對象也沒關(guān)系。因?yàn)檫@個類他本身就是共享的。

總結(jié):如上幾種方式進(jìn)行線程同步處理時,要注意你所使用的同步監(jiān)視器對象,它必須是共享的。

注:還有使用同步鎖的方式實(shí)現(xiàn)線程同步,本篇文章不做討論。

以上這篇淺談同步監(jiān)視器之同步代碼塊、同步方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 利用Java正則表達(dá)式校驗(yàn)郵箱與手機(jī)號

    利用Java正則表達(dá)式校驗(yàn)郵箱與手機(jī)號

    利用Java正則表達(dá)式校驗(yàn)郵箱與手機(jī)號。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10
  • 一小時迅速入門Mybatis之bind與多數(shù)據(jù)源支持 Java API

    一小時迅速入門Mybatis之bind與多數(shù)據(jù)源支持 Java API

    這篇文章主要介紹了一小時迅速入門Mybatis之bind與多數(shù)據(jù)源支持 Java API,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Java13 明天發(fā)布(最新最全新特性解讀)

    Java13 明天發(fā)布(最新最全新特性解讀)

    這篇文章主要介紹了Java13 明天發(fā)布,最新最全新特性解讀,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 解決IDEA中pom.xml文件變?yōu)榛疑膯栴}

    解決IDEA中pom.xml文件變?yōu)榛疑膯栴}

    這篇文章主要給大家介紹了如何解決IDEA中pom.xml文件變?yōu)榛疑膯栴},文中通過圖文結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12
  • 教你在一分鐘之內(nèi)理解Java Lambda表達(dá)式并學(xué)會使用

    教你在一分鐘之內(nèi)理解Java Lambda表達(dá)式并學(xué)會使用

    今天給大家?guī)У奈恼率荍ava8新特性的相關(guān)知識,文章圍繞著如何在一分鐘之內(nèi)理解Java Lambda表達(dá)式并學(xué)會使用展開,文中有非常詳細(xì)的介紹,需要的朋友可以參考下
    2021-06-06
  • SpringBoot生成PDF的五種實(shí)現(xiàn)方法總結(jié)

    SpringBoot生成PDF的五種實(shí)現(xiàn)方法總結(jié)

    這篇文章主要介紹了SpringBoot生成PDF的五種實(shí)現(xiàn)方法,在開發(fā)中經(jīng)常會遇到需要進(jìn)行對一些數(shù)據(jù)進(jìn)行動態(tài)導(dǎo)出PDF文件,然后讓用戶自己選擇是否需要打印出來,這篇文章我們來介紹五種實(shí)現(xiàn)方法,需要的朋友可以參考下
    2024-10-10
  • Java中的PowerMock使用實(shí)踐

    Java中的PowerMock使用實(shí)踐

    這篇文章主要介紹了Java中的PowerMock使用實(shí)踐,@PrepareForTest和@RunWith是成對出現(xiàn)的,一般@RunWith(PowerMockRunner.class),@PrepareForTest的值是引用的靜態(tài)方法或私有方法的類,需要的朋友可以參考下
    2023-12-12
  • java算法之二分查找法的實(shí)例詳解

    java算法之二分查找法的實(shí)例詳解

    這篇文章主要介紹了java算法之二分查找法的實(shí)例詳解的相關(guān)資料,這里提供簡單實(shí)例幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • Java實(shí)現(xiàn)大數(shù)運(yùn)算的實(shí)例代碼

    Java實(shí)現(xiàn)大數(shù)運(yùn)算的實(shí)例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)大數(shù)運(yùn)算的實(shí)例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟

    RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟

    這篇文章主要介紹了RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06

最新評論