“模拟银行”作业,多线程,除主线程外 设有CustomerGenerator线程:负责源源不断随机生成办理业务的顾客,顾客的操作类型、金额、业务时间都是随机 Teller线程:负责从等待顾客队列中抽取第一个顾客,办理业务
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ArrayBlockingQueue;
public class VirtualBank {
public static void main(String args[])throws Exception{
CustomerLine customers = new CustomerLine(50);
CustomerGenerator a = new CustomerGenerator(customers);
Teller b = new Teller(customers);
a.start();
b.start();
TimeUnit.SECONDS.sleep(5);
a.exit = true;
TimeUnit.SECONDS.sleep(4);
b.exit = true;
TimeUnit.SECONDS.sleep(1);
System.out.println("剩余的业务也处理完了,银行真的关门了!看看现在银行还剩多少钱吧:"+b.totalMoney);
}
}
//顾客类
class Customer
{
private final int serviceTime; //客户要求被服务的时间
private int balance; //客户的余额
public boolean deposit; //客户操作类型,如果为true则为存款,false为取款
public int money; //客户操作金额
public Customer(int serviceTime,int balance,int bool,int money)
{
this.serviceTime = serviceTime;
this.balance = balance;
if(bool==1)
this.deposit = true;
else
this.deposit = false;
this.money = money;
}
public int getServiceTime()
{
return serviceTime;
}
@Override
public String toString()
{
return "客户操作信息:[服务时间 =" + serviceTime + ","+"账户余额 ="+balance+","+"存款/取款 "+deposit+","+"金额 ="+money+"]";
}
public synchronized void withdrawal()
{
if(balance<money){
System.out.println("取款:"+money+" 余额:"+this.balance+" 余额不足!");
}
else{
balance = balance-money;
}
}
public synchronized void deposit()
{
balance = balance+money;
//System.out.println("新存入:"+money+" 共计:"+this.balance);
}
}
//顾客队列
/* ArrayBlockingQueue<Customer>
* 一个由数组支持的有界阻塞队列。
*此队列按 FIFO(先进先出)原则对元素进行排序。
*队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。
*新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。
*这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。
*一旦创建了这样的缓存区,就不能再增加其容量。
*试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。
*/
class CustomerLine extends ArrayBlockingQueue<Customer>
{
public CustomerLine(int maxLineSize) //数组的最大长度
{
super(maxLineSize);
}
@Override
public String toString()
{
if(this.size() == 0)
return "[没有顾客,为空]";
StringBuilder result = new StringBuilder();
for(Customer customer : this)
{
//把数组里面的顾客全部取出来,放到string里面去
result.append(customer);
}
return result.toString();
}
}
//顾客产生器,随机产生顾客 实现了Runnable接口的类
class CustomerGenerator extends Thread
{
Random rand = new Random();
public boolean exit = false;
//得到顾客的队列
private CustomerLine customers;
public CustomerGenerator(CustomerLine customers)
{
this.customers = customers;
}
@Override
public void run()
{
try
{
//只要当前线程没有被打断,那么我们就不断地产生新的顾客 while(!Thread.interrupted())
while(!exit)
{
//随机时间里面产生顾客,产生的顾客需求也是随机地,客户的初始余额也是随机的
TimeUnit.MILLISECONDS.sleep(rand.nextInt(1000));
//然后队列里面添加一个随机地顾客
customers.put(new Customer(rand.nextInt(1000),rand.nextInt(1000),rand.nextInt(2),rand.nextInt(1000))); //随机的顾客需求
}
}
catch (InterruptedException e)
{
System.out.println("顾客产生器线程被打断了");
e.printStackTrace();
}
System.out.println("打烊时间到!不允许新的顾客产生了!");
System.out.println("顾客产生器 终结(terminating)");
}
}
//银行出纳员类
class Teller extends Thread
{
public boolean exit = false;
private int customersServed = 0; //当前服务了多少顾客
private CustomerLine customers; //顾客队列
public int totalMoney = 10000;
public Teller(CustomerLine customers)
{
this.customers = customers;
}
@Override
public void run()
{
try
{
while(!exit)
{
if(customers.size() == 0){
continue;
}
//队列里面排第一个的顾客脱离队伍,接受服务
Customer customer = customers.take();
//这个要被服务的时间队列需要停顿,停顿时间有当前的customer决定
TimeUnit.MILLISECONDS.sleep(customer.getServiceTime());
//这时候要显示当前服务的顾客的信息
if(customer.deposit){
customer.deposit();
totalMoney += customer.money;
}
else{
customer.withdrawal();
totalMoney -= customer.money;
}
System.out.println(customer.toString());
//然后给服务数量加一
synchronized(this)
{
customersServed++;
System.out.println("当前服务顾客数:"+customersServed);
System.out.println("当前等待人数:"+customers.size());
System.out.println("银行余额:"+totalMoney);
}
}
}
catch (InterruptedException e)
{
System.out.println("exit3="+exit);
System.out.println(this + "被中断");
e.printStackTrace();
}
System.out.println("Teller线程结束!");
}
}