(三十一)java多线程二

因为线程在执行的过程中具有一定的不确定性,在并发的时候就会出现安全问题,因此一般需要采取一定的措施来保证线程的安全,同步代码块就是其中一种方式。

以下是模拟银行取钱的多线程小例子,两个都能确保安全,但是有一种却更好一些。

例1:

packagedemo1;

/**

*
模拟两个人同时取一个账户的钱,必须只能有一个人能取成功

*@authortuzongxun

*

*/

publicclass ThreadTest6 {

publicstaticvoidmain(String[]args)
{

// 创建一个用户账户

Account account = newAccount("tu", 1000);

// 创建两个线程模拟取钱

GetMoney get1 = newGetMoney("甲", account,
600);

GetMoney get2 = newGetMoney("乙", account,
500);

// 启动线程

get1.start();

get2.start();

}

}

/**

* 模拟账户

* @authortuzongxun

*

*/

class Account {

/**

* 账户名

*/

private StringaccountNum;

/**

* 账户余额

*/

private Doublemoney;

publicAccount(String accountNum,double money) {

this.accountNum = accountNum;

this.money = money;

}

public StringgetAccountNum() {

returnaccountNum;

}

publicvoidsetAccountNum(StringaccountNum) {

this.accountNum = accountNum;

}

public DoublegetMoney() {

returnmoney;

}

publicvoidsetMoney(Double money) {

this.money = money;

}

}

classGetMoneyextends
Thread {

privatefinaldoublenum;

privatefinal Accountaccount;

publicGetMoney(String name,Account account,double num) {

super(name);

this.num = num;

this.account = account;

}

@Override

publicvoidrun() {

/**

* 这里锁住了整个用户对象,所以先开始的线程会锁定对象,另一个不能获得对象,无法结束

* 只有当操作账户的线程结束后,另一个线程才能结束

*/

synchronized (account) {

if (account.getMoney() >num) {

account.setMoney(account.getMoney() -num);

System.out.println("用户(
" + this.getName()
+ " )取钱成功,取了("
+ account.getAccountNum()

+ ")的账户:" +num
+ "元");

System.out.println("账户余额:"
+ account.getMoney() +"元");

}else {

System.out.println("用户(
" + this.getName()
+ " )取钱失败");

System.out.println("账户余额:"
+ account.getMoney() +"元");

}

}

}

}

例2:

packagedemo1;

/**

* 模拟两个人同时取一个账户的钱,必须只能有一个人能取成功

* @authortuzongxun

*

*/

publicclass ThreadTest7 {

publicstaticvoidmain(String[]
args) {

Account1 account = newAccount1("tu", 1000);

newGetMoney1("甲", account, 600).start();

newGetMoney1("乙", account, 500).start();

}

}

/**

* 模拟账户

* @authortuzongxun

*

*/

class Account1 {

private StringaccountName;

privatedoublebalance;

publicAccount1(StringaccountName,double balance) {

this.accountName = accountName;

this.balance = balance;

}

public StringgetAccountName() {

returnaccountName;

}

publicvoidsetAccountName(StringaccountName) {

this.accountName = accountName;

}

publicdoublegetBalance() {

returnbalance;

}

publicvoidsetBalance(double balance) {

this.balance = balance;

}

/**

* 这里只是锁住了取钱的方法,所以有可能第一个线程运行一半时,第二个开始运行并可能先结束

*但是就算第一个后结束,第二个线程依然取钱失败。

*@param money

* @return

*/

publicsynchronizeddoublegetMondy(double
money) {

if (balance > money) {

balance -= money;

return 1;

} else {

return -1;

}

}

};

classGetMoney1extends
Thread {

privatefinal Account1account;

privatefinaldoublemoney;

publicGetMoney1(String name,Account1 account,double money) {

super(name);

this.account = account;

this.money = money;

}

@Override

publicvoidrun() {

double getMoney =account.getMondy(money);

if (getMoney > 0){

System.out.println(this.getName()
+ "取款成功,取了"
+ account.getAccountName() +"账户:"
+ money

+ "元");

System.out.println("账户余额:"
+ account.getBalance());

} else {

System.out.println(this.getName()
+ "取款失败");

System.out.println("账户余额:"
+ account.getBalance());

}

}

}

上一篇:Atitit 订单处理原理与功能设计attilax总结


下一篇:JS 无限长form表单提交