Java多线程模拟储蓄卡账户流水

模拟一个储蓄卡账户,起初额度是100元,模拟取现、存款等多次操作。 1.可以先取出1元,再存入1元,有1000次以上的流水即可。 2.输出结果可为示例:”向账户取了1元,账户还有X元“,或者”向账户存了1元,账户还有X元“。其中X为当前储蓄卡内的余额。 3.为了方便查看结果,流水次数最好以10的倍数。

我刚好写了一个,看看是不是你要的

 public class AccountTest {
    public static void main(String[] args) {
        Account account=new Account();
        Bank bank=new Bank();
        bank.setAccount(account);
        Thread t1=new Thread(new PeopleIn(bank));
        Thread t2=new Thread(new PeopleOut(bank));
        t1.setName("张三");
        t2.setName("张三的老婆");
        t1.start();
        t2.start();
    }
}
class Account{
    private int balance=100;
    public int getBalance(){
        return this.balance;
    }
    public void amountOut(int amt){
        balance=balance-amt;
        System.out.println(Thread.currentThread().getName()+"取款"+amt);
    }
    public void amountIn(int amt){
        balance=balance+amt;
        System.out.println(Thread.currentThread().getName()+"存款"+amt);
    }
}
class Bank{
    private Account account;
    private boolean flag=false;
    public void setAccount(Account account){
        this.account=account;
    }
    public Account getAccount(){
        return account;
    }
    public synchronized void moneyOut(int amt) {
            if(flag==false){
                try {
                    //System.out.println("老公还未存钱,余额不足。");
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(this.account.getBalance()>0){
                account.amountOut(amt);
                System.out.println("账户余额"+this.account.getBalance());
            }else {
                System.out.println("余额不足,无法完成取款。");
            }
            this.flag=false;
            this.notify();
        }

    public synchronized void moneyIn(int amt) {
            if(flag){
                try {
                    //System.out.println("老婆还未取钱,无法存钱。");
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(this.account.getBalance()<100){
                account.amountIn(amt);
                System.out.println("账户余额"+this.account.getBalance());
            }else {
                System.out.println("账户金额已满,无法完成存款。");
            }
            this.flag=true;
            this.notify();
        }
    }

class PeopleIn implements Runnable{
    private  Bank bank;
    public PeopleIn(Bank bank){
        this.bank=bank;
    }
    @Override
    public void run() {
        for(int i=0;i<20;i++){
        bank.moneyIn(100);
        }
    }
}
class PeopleOut implements Runnable{
    private  Bank bank;
    public PeopleOut(Bank bank){
        this.bank=bank;
    }
    @Override
    public void run() {
        for(int i=0;i<20;i++){
        bank.moneyOut(100);
        }
    }
}

http://blog.csdn.net/flueky/article/details/52713888

代码逻辑

取任务

/**
 * 从队列中取出任务
 * 
 * @author flueky zkf@yitong.com.cn
 * @date 2016年10月9日 下午6:47:12
 * @return 可能返回空,等待一段时间查询
 * @throws InterruptedException
 */
protected Task getTask() throws InterruptedException {
    if (taskQueue == null) {
        return null;
    }
    if (!taskQueue.get(0).isEmpty() || taskQueue.size() == 1) {// 当自己的任务队列非空,或者本本窗口只有属于自己的任务
        return taskQueue.get(0).take();// 从队头取出任务,如果任务队列空,则阻塞线程
    }
    for (int i = 1; i < taskQueue.size(); i++) {
        if (!taskQueue.get(i).isEmpty()) {// 存在非空的任务队列,取出任务处理
            System.err.println("处理其他窗口业务");
            return taskQueue.get(i).remove();//不阻塞线程
        }
    }
    return null;

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
这个方法是在Window中定义的,每次取新的业务时,考虑到快速业务和VIP业务不仅可以处理自身的业务也可以帮忙处理普通业务。所以,优先判断自身的任务队列。只有快速窗口和VIP窗口的自身任务队列是空,才处理普通窗口的任务队列。但是当普通窗口的任务队列也是空的时候,不阻塞该线程。
处理任务

@Override
public void run() {
    super.run();
    while(true){
        Task task = null;
        try {
            while ((task = getTask()) == null) {
                Thread.sleep(1000);
            }
            //标记业务被处理的窗口
            task.setWindow(this);
            System.out.println(getName() + "处理" + task.getId());
            //开始处理业务
            task.setStartTime(Calendar.getInstance());
            //休眠线程
            Thread.sleep(task.getCostTime());
            //结束处理业务
            task.setEndTime(Calendar.getInstance());
            listener.onTaskCompelete(task);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
窗口线程的处理程序,每次取出一个非空的task进行处理,如果队列是空,就休眠线程1秒钟,继续取出任务。
主线程

public void excute() {

    /**
     * 普通任务队列
     */
    BlockingQueue<Task> normalTasks = new ArrayBlockingQueue<Task>(100);
    /**
     * vip任务队列
     */
    BlockingQueue<Task> vipTasks = new ArrayBlockingQueue<Task>(100);
    /**
     * 快速业务队列
     */
    BlockingQueue<Task> quickTasks = new ArrayBlockingQueue<Task>(100);

    NormalWindow normalWindow1 = new NormalWindow("普通窗口1", this);
    NormalWindow normalWindow2 = new NormalWindow("普通窗口2", this);
    NormalWindow normalWindow3 = new NormalWindow("普通窗口3", this);
    NormalWindow normalWindow4 = new NormalWindow("普通窗口4", this);
    VIPWindow vipWindow = new VIPWindow("VIP窗口", this);
    QuickWindow quickWindow = new QuickWindow("快速窗口", this);

    /**
     * 添加处于本窗口管理的任务队列
     */
    normalWindow1.addTaskQueque(normalTasks);
    normalWindow2.addTaskQueque(normalTasks);
    normalWindow3.addTaskQueque(normalTasks);
    normalWindow4.addTaskQueque(normalTasks);
    vipWindow.addTaskQueque(vipTasks);
    quickWindow.addTaskQueque(quickTasks);

    /**
     * 给vip窗口和快速窗口添加普通窗口的任务队列
     */
    vipWindow.addTaskQueque(normalTasks);
    quickWindow.addTaskQueque(normalTasks);

    /**
     * 启动所有窗口的线程
     */
    normalWindow1.start();
    normalWindow2.start();
    normalWindow3.start();
    normalWindow4.start();
    vipWindow.start();
    quickWindow.start();

    while (true) {
        try {
            Task task = TaskFactory.generateTask();//生成业务
            System.out.println(task);
            //添加到指定的任务队列中
            if (task instanceof NormalTask)
                normalTasks.add(task);
            else if (task instanceof VIPTask)
                vipTasks.add(task);
            else
                quickTasks.add(task);
            //休眠1秒,继续生成下一个任务
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

http://blog.csdn.net/flueky/article/details/52713888