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

Java線程協(xié)調(diào)運(yùn)行操作實(shí)例詳解

 更新時(shí)間:2019年09月19日 10:59:24   作者:cakincqm  
這篇文章主要介紹了Java線程協(xié)調(diào)運(yùn)行操作,結(jié)合具體實(shí)例形式詳細(xì)分析了Java線程協(xié)調(diào)運(yùn)行原理、實(shí)現(xiàn)方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了Java線程協(xié)調(diào)運(yùn)行操作。分享給大家供大家參考,具體如下:

一 點(diǎn)睛

借助于Object類提供的wait()、notify()和notifyAll()三個(gè)方法,可實(shí)現(xiàn)Java線程協(xié)調(diào)運(yùn)行。這三個(gè)方法并不屬于Thread類,而是屬于Object類。但這三個(gè)方法必須同步監(jiān)視器對象調(diào)用。

關(guān)于這三個(gè)方法的解釋如下:

  • wait():導(dǎo)致當(dāng)前線程等待,直到其他線程調(diào)用該同步監(jiān)視器的notify()方法或notifyAll()方法來喚醒該線程。該wait()方法有三種形式:無時(shí)間參數(shù)的wait(一直等待,直到其他線程通知),帶毫秒?yún)?shù)的wait和帶毫秒、微秒?yún)?shù)的wait(這兩種方法都是等待指定時(shí)間后自動(dòng)蘇醒)。調(diào)用wait()方法的當(dāng)前線程會(huì)釋放對該同步監(jiān)視器的鎖定。
  • notify():喚醒在此同步監(jiān)視器上等待的單個(gè)線程。如果所有線程都在此同步監(jiān)視器上等待,則會(huì)選擇喚醒其中一個(gè)線程。選擇是任意性的。只有當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后(使用wait()方法),才可以執(zhí)行被喚醒的線程。
  • notifyAll():喚醒在此同步監(jiān)視器上等待的所有線程。只有當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后,才可以執(zhí)行被喚醒的線程。

對于使用synchronized修飾的同步方法,因?yàn)樵擃惖哪J(rèn)實(shí)例(this)就是同步監(jiān)視器,所以可以直接調(diào)用這三個(gè)方法。

對于使用synchronized修飾的同步塊,同步監(jiān)視器是synchronized后括號(hào)里的對象,所以必須使用該對象調(diào)用這三個(gè)方法。

二 實(shí)戰(zhàn)

1 Account類

public class Account
{
   // 封裝賬戶編號(hào)、賬戶余額的兩個(gè)成員變量
   private String accountNo;
   private double balance;
   // 標(biāo)識(shí)賬戶中是否已有存款的旗標(biāo)
   private boolean flag = false;
   public Account(){}
   // 構(gòu)造器
   public Account(String accountNo , double balance)
   {
      this.accountNo = accountNo;
      this.balance = balance;
   }
   // accountNo的setter和getter方法
   public void setAccountNo(String accountNo)
   {
      this.accountNo = accountNo;
   }
   public String getAccountNo()
   {
      return this.accountNo;
   }
   // 因此賬戶余額不允許隨便修改,所以只為balance提供getter方法,
   public double getBalance()
   {
      return this.balance;
   }
   public synchronized void draw(double drawAmount)
   {
      try
      {
        // 如果flag為假,表明賬戶中還沒有人存錢進(jìn)去,取錢方法阻塞
        if (!flag)
        {
           wait();
        }
        else
        {
           // 執(zhí)行取錢
           System.out.println(Thread.currentThread().getName()
              + " 取錢:" + drawAmount);
           balance -= drawAmount;
           System.out.println("賬戶余額為:" + balance);
           // 將標(biāo)識(shí)賬戶是否已有存款的旗標(biāo)設(shè)為false。
           flag = false;
           // 喚醒其他線程
           notifyAll();
        }
      }
      catch (InterruptedException ex)
      {
        ex.printStackTrace();
      }
   }
   public synchronized void deposit(double depositAmount)
   {
      try
      {
        // 如果flag為真,表明賬戶中已有人存錢進(jìn)去,則存錢方法阻塞
        if (flag)       //①
        {
           wait();
        }
        else
        {
           // 執(zhí)行存款
           System.out.println(Thread.currentThread().getName()
              + " 存款:" + depositAmount);
           balance += depositAmount;
           System.out.println("賬戶余額為:" + balance);
           // 將表示賬戶是否已有存款的旗標(biāo)設(shè)為true
           flag = true;
           // 喚醒其他線程
           notifyAll();
        }
      }
      catch (InterruptedException ex)
      {
        ex.printStackTrace();
      }
   }
   // 下面兩個(gè)方法根據(jù)accountNo來重寫hashCode()和equals()方法
   public int hashCode()
   {
      return accountNo.hashCode();
   }
   public boolean equals(Object obj)
   {
      if(this == obj)
        return true;
      if (obj !=null
        && obj.getClass() == Account.class)
      {
        Account target = (Account)obj;
        return target.getAccountNo().equals(accountNo);
      }
      return false;
   }
}

2 DrawThread線程類

public class DrawThread extends Thread
{
   // 模擬用戶賬戶
   private Account account;
   // 當(dāng)前取錢線程所希望取的錢數(shù)
   private double drawAmount;
   public DrawThread(String name , Account account
      , double drawAmount)
   {
      super(name);
      this.account = account;
      this.drawAmount = drawAmount;
   }
   // 重復(fù)100次執(zhí)行取錢操作
   public void run()
   {
      for (int i = 0 ; i < 100 ; i++ )
      {
        account.draw(drawAmount);
      }
   }
}

3 DepositThread線程類

public class DepositThread extends Thread
{
   // 模擬用戶賬戶
   private Account account;
   // 當(dāng)前取錢線程所希望存款的錢數(shù)
   private double depositAmount;
   public DepositThread(String name , Account account
      , double depositAmount)
   {
      super(name);
      this.account = account;
      this.depositAmount = depositAmount;
   }
   // 重復(fù)100次執(zhí)行存款操作
   public void run()
   {
      for (int i = 0 ; i < 100 ; i++ )
      {
        account.deposit(depositAmount);
      }
   }
}

4 測試類

public class DrawTest
{
   public static void main(String[] args)
   {
      // 創(chuàng)建一個(gè)賬戶
      Account acct = new Account("1234567" , 0);
      new DrawThread("取錢者" , acct , 800).start();
      new DepositThread("存款者甲" , acct , 800).start();
      new DepositThread("存款者乙" , acct , 800).start();
      new DepositThread("存款者丙" , acct , 800).start();
   }
}

三 運(yùn)行結(jié)果

......
存款者甲 存款:800.0
賬戶余額為:800.0
取錢者 取錢:800.0
賬戶余額為:0.0
存款者丙 存款:800.0
賬戶余額為:800.0
取錢者 取錢:800.0
賬戶余額為:0.0
存款者甲 存款:800.0
賬戶余額為:800.0

四 說明

運(yùn)行該程序,可以看到存款者線程、取錢者線程交替執(zhí)行的情形,每當(dāng)存款者向賬戶中存入800元之后,取錢這線程立即從賬戶中取出這筆錢。存款完成后賬戶余額總是800元,取錢結(jié)束后賬戶余額總是0元。

三個(gè)存款者線程隨機(jī)地向賬戶中存款,只有一個(gè)取錢者線程執(zhí)行取錢操作。只有當(dāng)取錢者取錢后,存款者才可以存款;同理,只有存款者存款后,取錢這線程才可以取錢。

程序最后被阻塞無法繼續(xù)向下執(zhí)行,這是因?yàn)?個(gè)存款者線程共300次存款操作,但1個(gè)取錢者線程只有100次操作,所以程序最后被阻塞。

更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java進(jìn)程與線程操作技巧總結(jié)》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 在springboot3微項(xiàng)目中如何用idea批量創(chuàng)建單元測試邏輯

    在springboot3微項(xiàng)目中如何用idea批量創(chuàng)建單元測試邏輯

    這篇文章主要介紹了在SpringBoot3項(xiàng)目中使用IntelliJIDEA批量創(chuàng)建單元測試包括準(zhǔn)備工作(確保項(xiàng)目配置正確,添加測試依賴),使用IntelliJIDEA創(chuàng)建測試,感興趣的朋友一起看看吧
    2024-10-10
  • 詳解如何配置Spring Batch批處理失敗重試機(jī)制

    詳解如何配置Spring Batch批處理失敗重試機(jī)制

    這篇文章主要來和大家一起探討一下如何在Spring批處理框架中配置重試邏輯,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-06-06
  • 基于SpringBoot和Hutool工具包實(shí)現(xiàn)驗(yàn)證碼的案例

    基于SpringBoot和Hutool工具包實(shí)現(xiàn)驗(yàn)證碼的案例

    隨著安全性的要求越來越高,目前項(xiàng)目中很多都會(huì)使用驗(yàn)證碼,只要涉及到登錄,絕大多數(shù)都會(huì)有驗(yàn)證的要求,驗(yàn)證碼的形式也是多種多樣,更復(fù)雜的圖形驗(yàn)證碼和行為驗(yàn)證碼已經(jīng)成為了更流行的趨勢,本文給大家介紹了SpringBoot Hutool實(shí)現(xiàn)驗(yàn)證碼的案例,需要的朋友可以參考下
    2024-05-05
  • 通過JDK源碼角度分析Long類詳解

    通過JDK源碼角度分析Long類詳解

    這篇文章主要給大家介紹了關(guān)于通過JDK源碼角度分析Long類的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用long類具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • spring?java?動(dòng)態(tài)獲取consul?K/V的方法

    spring?java?動(dòng)態(tài)獲取consul?K/V的方法

    這篇文章主要介紹了spring?java?動(dòng)態(tài)獲取consul?K/V的相關(guān)資料,主要包括springConsul配置kv路徑以及自動(dòng)注入consulKV到服務(wù)中,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • Knife4j?3.0.3?整合SpringBoot?2.6.4的詳細(xì)過程

    Knife4j?3.0.3?整合SpringBoot?2.6.4的詳細(xì)過程

    本文要講的是?Knife4j?3.0.3?整合SpringBoot?2.6.4,在SpringBoot?2.4以上的版本和之前的版本還是不一樣的,這個(gè)也容易導(dǎo)致一些問題,本文就這兩個(gè)版本的整合做一個(gè)實(shí)戰(zhàn)介紹
    2022-09-09
  • java ArrayList按照同一屬性進(jìn)行分組

    java ArrayList按照同一屬性進(jìn)行分組

    這篇文章主要介紹了java ArrayList按照同一屬性進(jìn)行分組的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 基于Flyway實(shí)現(xiàn)簡化Spring Boot項(xiàng)目部署

    基于Flyway實(shí)現(xiàn)簡化Spring Boot項(xiàng)目部署

    這篇文章主要介紹了基于Flyway實(shí)現(xiàn)簡化Spring Boot項(xiàng)目部署,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 一文帶你了解FastExcel的使用

    一文帶你了解FastExcel的使用

    我們知道?EasyExcel?在作者從阿里離職之后就停止維護(hù)了,但在前兩周?EasyExcel?原作者推出了他的升級(jí)版框架?FastExcel,下面小編就來和大家聊聊FastExcel的具體使用吧
    2024-12-12
  • java 查找替換pdf中的指定文本

    java 查找替換pdf中的指定文本

    這篇文章主要介紹了java 如何查找替換pdf中的指定文本,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12

最新評論

平南县| 平谷区| 芷江| 吉首市| 南京市| 凤台县| 保山市| 巴马| 华宁县| 澄迈县| 镇江市| 东乌珠穆沁旗| 微山县| 尼木县| 曲靖市| 隆昌县| 浙江省| 阿瓦提县| 汽车| 五华县| 蛟河市| 广宁县| 乌鲁木齐市| 榆林市| 永寿县| 阳春市| 鄂温| 尤溪县| 惠水县| 嫩江县| 青铜峡市| 临安市| 宣汉县| 丰宁| 淮北市| 中牟县| 桓仁| 健康| 赤城县| 无极县| 景宁|