Java銀行取錢線程安全問題實例分析
本文實例講述了Java銀行取錢線程安全問題。分享給大家供大家參考,具體如下:
一 定義一個賬戶類
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;
}
}
二 定義一個取錢線程
public class DrawThread extends Thread
{
// 模擬用戶賬戶
private Account account;
// 當前取錢線程所希望取的錢數(shù)
private double drawAmount;
public DrawThread(String name , Account account
, double drawAmount)
{
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
// 當多條線程修改同一個共享數(shù)據(jù)時,將涉及數(shù)據(jù)安全問題。
public void run()
{
// 賬戶余額大于取錢數(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() + "取錢失??!余額不足!");
}
}
}
三 測試主類
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();
}
}
四 運行
乙取錢成功!吐出鈔票:800.0
甲取錢成功!吐出鈔票:800.0
余額為: 200.0
余額為: -600.0
五 說明
賬戶余額只有1000時取出1600,而且賬戶余額出現(xiàn)了負數(shù),這部是銀行希望看到的結(jié)果。
雖然上面程序是人為地使用Thread.sleep(1)來強制線程調(diào)度切換,但這種切換是完全可能發(fā)生的。
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java進程與線程操作技巧總結(jié)》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計有所幫助。
相關(guān)文章
Java使用RandomAccessFile類對文件進行讀寫
本篇文章主要介紹了Java使用RandomAccessFile類對文件進行讀寫,詳細的介紹了RandomAccessFile類的使用技巧和實例應用,有興趣的可以了解一下2017-04-04
Idea代理設(shè)置與Java程序的代理設(shè)置方式
文章總結(jié):學習WebService時,使用Fiddler抓取包數(shù)據(jù),發(fā)現(xiàn)Idea代理設(shè)置與Java程序代理設(shè)置不同,Java程序需要在發(fā)送請求前設(shè)置代理,代碼如下2025-01-01
IntelliJ IDEA 報錯:找不到包或者找不到符號的問題及解決方案
這篇文章主要介紹了IntelliJ IDEA 報錯:找不到包或者找不到符號的問題及解決方案,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
Java連接MySQL8.0 JDBC的詳細步驟(IDEA版本)
這篇文章主要介紹了Java連接MySQL8.0 JDBC的詳細步驟(IDEA版本),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
SpringBoot結(jié)合Tess4J實現(xiàn)拍圖識字的示例代碼
圖片中的文字提取已經(jīng)越來越多地應用于數(shù)據(jù)輸入和自動化處理過程,本文主要介紹了SpringBoot結(jié)合Tess4J實現(xiàn)拍圖識字的示例代碼,具有一定的參考價值,感興趣的可以了解一下2024-06-06

