真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java中怎么實現(xiàn)線程協(xié)調(diào)運行操作

本篇文章給大家分享的是有關(guān)Java中怎么實現(xiàn)線程協(xié)調(diào)運行操作,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

成都創(chuàng)新互聯(lián)是一家專注于做網(wǎng)站、網(wǎng)站設(shè)計與策劃設(shè)計,獻(xiàn)縣網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十余年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:獻(xiàn)縣等地區(qū)。獻(xiàn)縣做網(wǎng)站價格咨詢:18982081108

一 點睛

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

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

  • wait():導(dǎo)致當(dāng)前線程等待,直到其他線程調(diào)用該同步監(jiān)視器的notify()方法或notifyAll()方法來喚醒該線程。該wait()方法有三種形式:無時間參數(shù)的wait(一直等待,直到其他線程通知),帶毫秒?yún)?shù)的wait和帶毫秒、微秒?yún)?shù)的wait(這兩種方法都是等待指定時間后自動蘇醒)。調(diào)用wait()方法的當(dāng)前線程會釋放對該同步監(jiān)視器的鎖定。

  • notify():喚醒在此同步監(jiān)視器上等待的單個線程。如果所有線程都在此同步監(jiān)視器上等待,則會選擇喚醒其中一個線程。選擇是任意性的。只有當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后(使用wait()方法),才可以執(zhí)行被喚醒的線程。

  • notifyAll():喚醒在此同步監(jiān)視器上等待的所有線程。只有當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后,才可以執(zhí)行被喚醒的線程。

對于使用synchronized修飾的同步方法,因為該類的默認(rèn)實例(this)就是同步監(jiān)視器,所以可以直接調(diào)用這三個方法。

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

二 實戰(zhàn)

1 Account類

public class Account
{
   // 封裝賬戶編號、賬戶余額的兩個成員變量
   private String accountNo;
   private double balance;
   // 標(biāo)識賬戶中是否已有存款的旗標(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)識賬戶是否已有存款的旗標(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();
      }
   }
   // 下面兩個方法根據(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)建一個賬戶
      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();
   }
}

三 運行結(jié)果

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

以上就是Java中怎么實現(xiàn)線程協(xié)調(diào)運行操作,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


網(wǎng)站名稱:Java中怎么實現(xiàn)線程協(xié)調(diào)運行操作
標(biāo)題網(wǎng)址:http://weahome.cn/article/ihdjij.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部