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

Java同步代碼塊解決銀行取錢的安全問題實(shí)例分析

 更新時間:2019年08月27日 09:39:31   作者:cakincqm  
這篇文章主要介紹了Java同步代碼塊解決銀行取錢的安全問題,結(jié)合實(shí)例形式分析了java基于線程的同步問題實(shí)現(xiàn)與使用相關(guān)操作技巧,需要的朋友可以參考下

本文實(shí)例講述了Java同步代碼塊解決銀行取錢的安全問題。分享給大家供大家參考,具體如下:

一 點(diǎn)睛

為了解決類似銀行取錢這類安全問題,Java的多線程支持引入了同步監(jiān)視器來解決這個問題,使用同步監(jiān)視器的通用方法是同步代碼塊。同步代碼塊的語法格式是:

synchronized(obj)
{
  //此處代碼塊就是同步代碼塊。
}

上面語法格式中種的obj就是同步監(jiān)視器,上面代碼的含義是:線程開始執(zhí)行同步代碼塊之前,必須先獲得對同步監(jiān)視器的鎖定。

任何時刻只能由一個線程獲得對同步監(jiān)視器的鎖定,當(dāng)同步代碼塊執(zhí)行完成后,該線程會釋放對該同步監(jiān)視器的鎖定。

雖然Java程序允許使用任何對象作為同步監(jiān)視器,但想一下同步監(jiān)視器的目的:阻止兩個線程對同一共享資源進(jìn)行并發(fā)訪問,因此通常推薦使用可能被并發(fā)訪問的共享資源作為同步監(jiān)視器。

二 代碼

1 定義一個賬戶類

public class Account
{
   // 封裝賬戶編號、賬戶余額的兩個成員變量
   private String accountNo;
   private double balance;
   public Account(){}
   // 構(gòu)造器
   public Account(String accountNo , double balance)
   {
      this.accountNo = accountNo;
      this.balance = balance;
   }
   // 此處省略了accountNo和balance的setter和getter方法
   // accountNo的setter和getter方法
   public void setAccountNo(String accountNo)
   {
      this.accountNo = accountNo;
   }
   public String getAccountNo()
   {
      return this.accountNo;
   }
   // balance的setter和getter方法
   public void setBalance(double balance)
   {
      this.balance = balance;
   }
   public double getBalance()
   {
      return this.balance;
   }
   // 下面兩個方法根據(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 定義一個取錢線程

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;
   }
   // 當(dāng)多條線程修改同一個共享數(shù)據(jù)時,將涉及數(shù)據(jù)安全問題。
   public void run() {
      synchronized (account) {
        // 賬戶余額大于取錢數(shù)目
        if (account.getBalance() >= drawAmount) {
           // 吐出鈔票
           System.out.println(getName() + "取錢成功!吐出鈔票:" + drawAmount);
           try {
              Thread.sleep(1);
           } catch (InterruptedException ex) {
              ex.printStackTrace();
           }
           // 修改余額
           account.setBalance(account.getBalance() - drawAmount);
           System.out.println("\t余額為: " + account.getBalance());
        } else {
           System.out.println(getName() + "取錢失??!余額不足!");
        }
      }
   }
}

3 測試主類

public class DrawTest
{
   public static void main(String[] args)
   {
      // 創(chuàng)建一個賬戶
      Account acct = new Account("1234567" , 1000);
      // 模擬兩個線程對同一個賬戶取錢
      new DrawThread("甲" , acct , 800).start();
      new DrawThread("乙" , acct , 800).start();
   }
}

三 運(yùn)行

甲取錢成功!吐出鈔票:800.0
     余額為: 200.0
乙取錢失??!余額不足!

四 說明

使用synchronized將run()方法里的方法體修改為同步代碼塊,該同步代碼塊的同步監(jiān)視器是account對象,這樣的做法符合“加鎖->修改->釋放鎖”的邏輯,任何線程在修改指定資源之前,首先對該資源加鎖,在加鎖期間其他線程無法修改該資源,當(dāng)該線程修改完成后,該線程釋放對該資源的鎖定。通過這種方式就可以保證并發(fā)線程任一時刻只有一個線程可以進(jìn)入修改共享資源的代碼區(qū)(也稱臨界區(qū)),所以同一時刻最多只有一個線程處于臨界區(qū),從而保證線程的安全。

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

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

相關(guān)文章

  • logback?OutputStreamAppender高效日志輸出源碼解析

    logback?OutputStreamAppender高效日志輸出源碼解析

    這篇文章主要介紹了為大家logback?OutputStreamAppender日志輸出效率提升示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • IDEA導(dǎo)入jar包的完整實(shí)現(xiàn)步驟

    IDEA導(dǎo)入jar包的完整實(shí)現(xiàn)步驟

    由于導(dǎo)入jar包項(xiàng)目存在很多不確定的問題,導(dǎo)致每次都需要調(diào)試、配置好多遍,對此特意記錄下來,這篇文章主要給大家介紹了關(guān)于IDEA導(dǎo)入jar包的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • Spring Cloud如何使用Feign構(gòu)造多參數(shù)的請求

    Spring Cloud如何使用Feign構(gòu)造多參數(shù)的請求

    這篇文章主要介紹了Spring Cloud如何使用Feign構(gòu)造多參數(shù)的請求,以GET以及POST方法的請求為例進(jìn)行講解,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Java生成隨機(jī)數(shù)的方法

    Java生成隨機(jī)數(shù)的方法

    本篇文章主要介紹了Java生成隨機(jī)數(shù)的方法,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-05-05
  • 一篇文章帶你入門Java多線程

    一篇文章帶你入門Java多線程

    這篇文章主要介紹了java多線程編程實(shí)例,分享了幾則多線程的實(shí)例代碼,具有一定參考價值,加深多線程編程的理解還是很有幫助的,需要的朋友可以參考下
    2021-08-08
  • System.identityHashCode和hashCode的區(qū)別及說明

    System.identityHashCode和hashCode的區(qū)別及說明

    String調(diào)用hashCode()和System.identityHashCode()返回值不同是因?yàn)镾tring重寫了hashCode()方法,而System.identityHashCode()返回對象的內(nèi)存地址哈希值;Test調(diào)用兩個方法返回值相同是因?yàn)門est沒有重寫hashCode()方法,因此兩者調(diào)用底層的JVM_IHashCode方法返回相同值
    2024-11-11
  • Java?CAS機(jī)制詳解

    Java?CAS機(jī)制詳解

    這篇文章主要介紹了Java?CAS機(jī)制,CAS機(jī)制是一種數(shù)據(jù)更新的方式。在具體講什么是CAS機(jī)制之前,我們先來聊下在多線程環(huán)境下,對共享變量進(jìn)行數(shù)據(jù)更新的兩種模式:悲觀鎖模式和樂觀鎖模式
    2023-01-01
  • JAVA文件讀寫操作詳解

    JAVA文件讀寫操作詳解

    這篇文章主要為大家詳細(xì)介紹了JAVA文件讀寫操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • JAVA實(shí)現(xiàn)將磁盤中所有空文件夾進(jìn)行刪除的代碼

    JAVA實(shí)現(xiàn)將磁盤中所有空文件夾進(jìn)行刪除的代碼

    這篇文章主要介紹了JAVA實(shí)現(xiàn)將磁盤中所有空文件夾進(jìn)行刪除的代碼,需要的朋友可以參考下
    2017-06-06
  • 聊聊Spring?Cloud?Gateway過濾器精確控制異常返回問題

    聊聊Spring?Cloud?Gateway過濾器精確控制異常返回問題

    這篇文章主要介紹了Spring?Cloud?Gateway過濾器精確控制異常返回問題,本篇任務(wù)就是分析上述現(xiàn)象的原因,通過閱讀源碼搞清楚返回碼和響應(yīng)body生成的具體邏輯,需要的朋友可以參考下
    2021-11-11

最新評論

安阳县| 兴和县| 富民县| 中西区| 贺兰县| 腾冲县| 罗江县| 化州市| 布尔津县| 揭东县| 保定市| 九台市| 铜梁县| 彭州市| 名山县| 湖州市| 永昌县| 怀化市| 东方市| 柳林县| 夹江县| 仁寿县| 陵水| 桃江县| 白河县| 游戏| 油尖旺区| 平罗县| 明星| 惠安县| 沙洋县| 武城县| 牙克石市| 郁南县| 彭泽县| 慈利县| 雷州市| 上虞市| 溧水县| 石柱| 石家庄市|