中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Java中使用Condition控制線程通信

發布時間:2021-05-17 17:38:20 來源:億速云 閱讀:130 作者:Leah 欄目:編程語言

本篇文章給大家分享的是有關如何在Java中使用Condition控制線程通信,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

一 點睛

當使用Lock對象來保證同步時,Java提供了一個Condition類來保持協調,使用Condition可以讓那些已經得到Lock對象、卻無法繼續執行的線程釋放Lock對象,Condtion對象也可以喚醒其他處于等待的線程。

Condition 將同步監視鎖方法(wait、notify 和 notifyAll)分解成截然不同的對象,以便通過將這些對象與Lock對象組合使用,為每個對象提供多個等待集(wait-set)。在這種情況下,Lock 替代了同步方法或同步代碼塊,Condition替代了同步監視鎖的功能。

Condition實例實質上被綁定在一個Lock對象上。要獲得特定Lock實例的Condition實例,調用Lock對象newCondition()方法即可。Condtion類提供了如下三個方法:

await():類似于隱式同步監視器上的wait()方法,導致當前線程等待,直到其他線程調用該Condtion的signal ()方法或signalAll ()方法來喚醒該線程。該await方法有更多變體:long awaitNanos(long nanosTimeout)、void awaitUninterruptibly()、awaitUntil(Date deadline)等,可以完成更豐富的等待操作。

signal ():喚醒在此Lock對象上等待的單個線程。如果所有線程都在該Lock對象上等待,則會選擇喚醒其中一個線程。選擇是任意性的。只有當前線程放棄對該Lock對象的鎖定后(使用await()方法),才可以執行被喚醒的線程。

signalAll():喚醒在此Lock對象上等待的所有線程。只有當前線程放棄對該該Lock對象的鎖定后,才可以執行被喚醒的線程。

二 代碼

1 Account類

public class Account
{
   // 顯式定義Lock對象
   private final Lock lock = new ReentrantLock();
   // 獲得指定Lock對象對應的Condition
   private final Condition cond = lock.newCondition();
   // 封裝賬戶編號、賬戶余額的兩個成員變量
   private String accountNo;
   private double balance;
   // 標識賬戶中是否已有存款的旗標
   private boolean flag = false;
   public Account(){}
   // 構造器
   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 void draw(double drawAmount)
   {
      // 加鎖
      lock.lock();
      try
      {
        // 如果flag為假,表明賬戶中還沒有人存錢進去,取錢方法阻塞
        if (!flag)
        {
           cond.await();
        }
        else
        {
           // 執行取錢
           System.out.println(Thread.currentThread().getName()
              + " 取錢:" + drawAmount);
           balance -= drawAmount;
           System.out.println("賬戶余額為:" + balance);
           // 將標識賬戶是否已有存款的旗標設為false。
           flag = false;
           // 喚醒其他線程
           cond.signalAll();
        }
      }
      catch (InterruptedException ex)
      {
        ex.printStackTrace();
      }
      // 使用finally塊來釋放鎖
      finally
      {
        lock.unlock();
      }
   }
   public void deposit(double depositAmount)
   {
      lock.lock();
      try
      {
        // 如果flag為真,表明賬戶中已有人存錢進去,則存錢方法阻塞
        if (flag)       // ①
        {
           cond.await();
        }
        else
        {
           // 執行存款
           System.out.println(Thread.currentThread().getName()
              + " 存款:" + depositAmount);
           balance += depositAmount;
           System.out.println("賬戶余額為:" + balance);
           // 將表示賬戶是否已有存款的旗標設為true
           flag = true;
           // 喚醒其他線程
           cond.signalAll();
        }
      }
      catch (InterruptedException ex)
      {
        ex.printStackTrace();
      }
      // 使用finally塊來釋放鎖
      finally
      {
        lock.unlock();
      }
   }
   // 下面兩個方法根據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;
   // 當前取錢線程所希望取的錢數
   private double drawAmount;
   public DrawThread(String name , Account account
      , double drawAmount)
   {
      super(name);
      this.account = account;
      this.drawAmount = drawAmount;
   }
   // 重復100次執行取錢操作
   public void run()
   {
      for (int i = 0 ; i < 100 ; i++ )
      {
        account.draw(drawAmount);
      }
   }
}

3 DepositThread線程類

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

4 測試類

public class DrawTest
{
   public static void main(String[] args)
   {
      // 創建一個賬戶
      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();
   }
}

三 運行結果

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

Java的特點有哪些

Java的特點有哪些 1.Java語言作為靜態面向對象編程語言的代表,實現了面向對象理論,允許程序員以優雅的思維方式進行復雜的編程。 2.Java具有簡單性、面向對象、分布式、安全性、平臺獨立與可移植性、動態性等特點。 3.使用Java可以編寫桌面應用程序、Web應用程序、分布式系統和嵌入式系統應用程序等。

以上就是如何在Java中使用Condition控制線程通信,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潜山县| 工布江达县| 苗栗县| 横峰县| 耒阳市| 绥阳县| 邵阳县| 济南市| 马公市| 个旧市| 闽侯县| 芒康县| 博兴县| 柏乡县| 仙桃市| 和龙市| 禄丰县| 常熟市| 那坡县| 兰州市| 甘孜县| 昔阳县| 南京市| 麻栗坡县| 汤原县| 巢湖市| 普格县| 伊宁县| 灵石县| 巴南区| 务川| 西峡县| 班玛县| 湘西| 密云县| 鞍山市| 江西省| 沙雅县| 那坡县| 清河县| 永川市|