Java多线程经典例题之二--银行
2017-04-15 20:21
204 查看
银行帐户的存取款线程设计。
本例设计四个类,银行帐户类Account、存款线程类Deposit和取款线程类Withdraw,以及一个测试类AccountTest。
首先对银行账户进行定义,其中我们应该将属性定义为私有加以封装,由于此题主要是为了实现同步线程,所以设计太过于详细的要求你,只是简单的设计了用户和余额。
银行用户类:
public class Account {
//账号
private String account;
//余额
private double amount;
public Account() {
// TODO Auto-generated constructor stub
}
public Account(String account, double amount) {
super();
this.account = account;
this.amount = amount;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}
存钱类:
/**
* 存钱线程
*
*
* @author 睿源
*
*/
public class Deposit extends Thread{
//定义账号(余额)
Account account;
public Deposit(Account account) {
super();
this.account = account;
}
@Override
public void run() {
while(true){
//这里是入口,但是有锁,你得拿到钥匙才能进去
synchronized (account) {
//每次存1000以内的金额
//余额要等于原来的余额+每次存的金额
int random = (int)(Math.random()*1000)+1;
account.setAmount(account.getAmount()+random);
account.notify();
System.out.println(Thread.currentThread().getName()+":存款金额是:"+random+",当前余额是:"+account.getAmount());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
//方法结束后,就释放锁
}
}
}
取钱类:
测试类:
public class AccountTest {
public static void main(String[] args) {
Account account = new Account();
Thread deposit = new Deposit(account);
Thread withdraw = new Withdraw(account);
deposit.setName("存钱");
withdraw.setName("取钱");
deposit.start();
withdraw.start();
}
}
运行结果如下:
存钱:存款金额是:211,当前余额是:211.0
取钱:您要取:246,但是您的余额不足!您的余额是:211.0
存钱:存款金额是:968,当前余额是:1179.0
存钱:存款金额是:105,当前余额是:1284.0
存钱:存款金额是:119,当前余额是:1403.0
取钱:取现金额是58,余额是:1345.0
存钱:存款金额是:219,当前余额是:1564.0
取钱:取现金额是275,余额是:1289.0
取钱:取现金额是457,余额是:832.0
取钱:取现金额是67,余额是:765.0
取钱:取现金额是502,余额是:263.0
取钱:您要取:815,但是您的余额不足!您的余额是:263.0
存钱:存款金额是:402,当前余额是:665.0
Synchronized锁定一段代码,称为创建一个代码临界区,使得线程必须等候特定资源的所有权。
当第一个线程执行这段代码时,它获取特定的对象的所有权,即拥有该对象的锁。此时,如果有第二个线程对同一个对象也要执行这段代码时,它试图获取该对象的所有权,但因该对象已被锁定,则第二个线程必须等待,直到锁被释放为止。第一个线程执行完<语句>后,自动释放了锁,接下去第二个线程获得锁并可运行。这样就形成了多个线程对同一个对象的“互斥”使用方式,该对象称为“同步对象”。这种锁定方式是针对某个特定对象而言的。如果有两个线程同时对两个不同的对象进行操作,则没有锁定,它们可以同时进入代码的临界区。
银行帐户的存取款线程设计。
本例设计四个类,银行帐户类Account、存款线程类Deposit和取款线程类Withdraw,以及一个测试类AccountTest。
首先对银行账户进行定义,其中我们应该将属性定义为私有加以封装,由于此题主要是为了实现同步线程,所以设计太过于详细的要求你,只是简单的设计了用户和余额。
银行用户类:
public class Account {
//账号
private String account;
//余额
private double amount;
public Account() {
// TODO Auto-generated constructor stub
}
public Account(String account, double amount) {
super();
this.account = account;
this.amount = amount;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}
存钱类:
/**
* 存钱线程
*
*
* @author 睿源
*
*/
public class Deposit extends Thread{
//定义账号(余额)
Account account;
public Deposit(Account account) {
super();
this.account = account;
}
@Override
public void run() {
while(true){
//这里是入口,但是有锁,你得拿到钥匙才能进去
synchronized (account) {
//每次存1000以内的金额
//余额要等于原来的余额+每次存的金额
int random = (int)(Math.random()*1000)+1;
account.setAmount(account.getAmount()+random);
account.notify();
System.out.println(Thread.currentThread().getName()+":存款金额是:"+random+",当前余额是:"+account.getAmount());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
//方法结束后,就释放锁
}
}
}
取钱类:
public class Withdraw extends Thread{ Account account; public Withdraw(Account account) { super(); this.account = account; } @Override public void run() { while(true){ synchronized (account) { int random = (int)(Math.random()*1000)+1; //如果要取出的金额大于账户的余额 if(random > account.getAmount()){ try { System.out.println(Thread.currentThread().getName()+":您要取:"+random+",但是您的余额不足!您的余额是:"+account.getAmount()); account.wait(); } catch (InterruptedException e) { } }else{ //执行取钱操作 account.setAmount(account.getAmount()-random); System.out.println(Thread.currentThread().getName()+":取现金额是"+random+",余额是:"+account.getAmount()); } } } } }
测试类:
public class AccountTest {
public static void main(String[] args) {
Account account = new Account();
Thread deposit = new Deposit(account);
Thread withdraw = new Withdraw(account);
deposit.setName("存钱");
withdraw.setName("取钱");
deposit.start();
withdraw.start();
}
}
运行结果如下:
存钱:存款金额是:211,当前余额是:211.0
取钱:您要取:246,但是您的余额不足!您的余额是:211.0
存钱:存款金额是:968,当前余额是:1179.0
存钱:存款金额是:105,当前余额是:1284.0
存钱:存款金额是:119,当前余额是:1403.0
取钱:取现金额是58,余额是:1345.0
存钱:存款金额是:219,当前余额是:1564.0
取钱:取现金额是275,余额是:1289.0
取钱:取现金额是457,余额是:832.0
取钱:取现金额是67,余额是:765.0
取钱:取现金额是502,余额是:263.0
取钱:您要取:815,但是您的余额不足!您的余额是:263.0
存钱:存款金额是:402,当前余额是:665.0
Synchronized锁定一段代码,称为创建一个代码临界区,使得线程必须等候特定资源的所有权。
当第一个线程执行这段代码时,它获取特定的对象的所有权,即拥有该对象的锁。此时,如果有第二个线程对同一个对象也要执行这段代码时,它试图获取该对象的所有权,但因该对象已被锁定,则第二个线程必须等待,直到锁被释放为止。第一个线程执行完<语句>后,自动释放了锁,接下去第二个线程获得锁并可运行。这样就形成了多个线程对同一个对象的“互斥”使用方式,该对象称为“同步对象”。这种锁定方式是针对某个特定对象而言的。如果有两个线程同时对两个不同的对象进行操作,则没有锁定,它们可以同时进入代码的临界区。
相关文章推荐
- Java中的多线程—经典例题
- Java多线程经典例题一
- 经典:Java及相关字符集编码问题研究 之二
- 深刻剖析经典面试题之二:Java与C#的垃圾回收机制
- JAVA多线程学习初步经典实例
- java多线程(java开发实战经典 知识点2)
- java多线程交互 经典实例__生产者与消费者模型
- 深刻剖析经典面试题之二:Java与C#的垃圾回收机制
- java并发编程--一道经典多线程题的2种解法
- java经典例题
- Java经典算法例题分享
- 黑马程序员__java多线程总结(含经典实例!)
- java一个多线程的经典例子
- 经典多线程Java实例 生产者与消费者
- JAVA多线程经典例子
- java经典例题
- java多线程经典实例
- 用JAVA的多线程实现银行取款的问题
- java一个多线程的经典例子
- java多线程总结六:经典生产者消费者问题实现