1. 程式人生 > >Java 多執行緒 模擬銀行ATM實時存取錢

Java 多執行緒 模擬銀行ATM實時存取錢

近期想回顧一些知識:
一、Java 多執行緒
一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。多執行緒是多工的一種特別的形式,但多執行緒使用了更小的資源開銷。這裡定義和執行緒相關的另一個術語 - 程序:一個程序包括由作業系統分配的記憶體空間,包含一個或多個執行緒。一個執行緒不能獨立的存在,它必須是程序的一部分。一個程序一直執行,直到所有的非守護執行緒都結束執行後才能結束。多執行緒能滿足程式設計師編寫高效率的程式來達到充分利用 CPU 的目的。

二、區別

  • 程序:每個程序都有獨立的程式碼和資料空間(程序上下文),程序間的切換會有較大的開銷,一個程序包含1–n個執行緒。(程序是資源分配的最小單位)
  • 執行緒:同一類執行緒共享程式碼和資料空間,每個執行緒有獨立的執行棧和程式計數器(PC),執行緒切換開銷小。(執行緒是cpu排程的最小單位)
  • 執行緒和程序一樣分為五個階段:建立、就緒、執行、阻塞、終止。
  • 多程序是指作業系統能同時執行多個任務(程式)。
  • 多執行緒是指在同一程式中有多個順序流在執行。

三、模擬銀行ATM存取錢
1、 使用者類user,儲存使用者資訊

import java.util.Date;
public class User {
    private String u_name;//使用者名稱
    private String u_login_name;//登入名 卡的id
private String u_login_pwd;//登入密碼 private String u_wallet;//錢包 private Date draw_money_time;//取錢時間 private Date save_money_time;//存錢時間 public User(){} public User(String u_name, String u_login_name, String u_login_pwd, String u_wallet) { this.u_name = u_name; this.u_login_name = u_login_name; this
.u_login_pwd = u_login_pwd; this.u_wallet = u_wallet; } public User(String u_name, String u_login_name, String u_login_pwd, String u_wallet, Date draw_money_time, Date save_money_time) { this.u_name = u_name; this.u_login_name = u_login_name; this.u_login_pwd = u_login_pwd; this.u_wallet = u_wallet; this.draw_money_time = draw_money_time; this.save_money_time = save_money_time; } public String getU_name() { return u_name; } public void setU_name(String u_name) { this.u_name = u_name; } public String getU_login_name() { return u_login_name; } public void setU_login_name(String u_login_name) { this.u_login_name = u_login_name; } public String getU_login_pwd() { return u_login_pwd; } public void setU_login_pwd(String u_login_pwd) { this.u_login_pwd = u_login_pwd; } public String getU_wallet() { return u_wallet; } public void setU_wallet(String u_wallet) { this.u_wallet = u_wallet; } public Date getDraw_money_time() { return draw_money_time; } public void setDraw_money_time(Date draw_money_time) { this.draw_money_time = draw_money_time; } public Date getSave_money_time() { return save_money_time; } public void setSave_money_time(Date save_money_time) { this.save_money_time = save_money_time; } }

2、 取款類ATM:有取款機的相應功能

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * 取款機
 * 2018/6/8
 * wtj
 */
public class ATM {
    private List<User> userList=new ArrayList<>();
    public ATM(){}

    public  ATM(List<User> userList) {
         this.userList = userList;
    }

    public  List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }
    //存錢
    public Boolean saveMoney(String card,String pwd,String moneyNum){
        User u=getUserByCard(card);
        synchronized (ATM.class) {
                if (u.getU_login_name().equals(card) && u.getU_login_pwd().equals(pwd)) {
                    BigDecimal oldData=new BigDecimal(u.getU_wallet());
                    BigDecimal money=new BigDecimal(moneyNum);
                    u.setU_wallet(oldData.add(money).toString());
                    u.setSave_money_time(new Date());
                    System.out.println(Thread.currentThread().getName()+"存錢---->"+u.getU_name()+"在"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(u.getSave_money_time())+"存["+moneyNum+"]錢,餘額:"+u.getU_wallet());
                    return true;
                }
            }
        System.out.println(getUserByCard(card).getU_name()+"存錢失敗");
      return false;
    }
    //取錢
    public Boolean getMoney(String card,String pwd,String moneyNum){
        User u=getUserByCard(card);
        synchronized (ATM.class) {
                if (u!=null && u.getU_login_name().equals(card) && u.getU_login_pwd().equals(pwd)) {
                    BigDecimal oldData=new BigDecimal(u.getU_wallet());
                    BigDecimal money=new BigDecimal(moneyNum);
                    if(oldData.compareTo(money)>=0){
                        u.setU_wallet(oldData.subtract(money).toString());
                        u.setDraw_money_time(new Date());
                        System.out.println(Thread.currentThread().getName()+"取錢---->"+u.getU_name()+"在"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(u.getDraw_money_time())+"取["+moneyNum+"]錢,餘額:"+u.getU_wallet());
                        return true;
                    }else {
                        System.out.println(getUserByCard(card).getU_name()+"餘額不足");
                        return false;
                    }
                }
            }
        System.out.println(card+"取錢失敗");
        return false;
    }
    //查詢餘額
    public String balanceEnquiry(String card,String pwd){
        for(User u :this.userList){
            if(u.getU_login_name().equals(card)&& u.getU_login_pwd().equals(pwd)){
                System.out.println(Thread.currentThread().getName()+":"+u.getU_name()+"餘額:"+u.getU_wallet());
                return u.getU_wallet();
            }
        }
        System.out.println(Thread.currentThread().getName()+":"+card+"操作失敗");
        return null;
    }
   //獲取當前使用者
    public synchronized User getUserByCard(String card){
        for(User u :this.userList){
            if(u.getU_login_name().equals(card)){
                return u;
            }
        }
        return null;
    }
    public void delayTime(Integer nim){
        try {
            Thread.sleep(nim);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3、測試類:模擬多次存取錢

import java.util.ArrayList;
import java.util.List;

public class TreadTextMain {
    public static void main(String[] args) throws Exception {
        User u = new User("趙雲", "132466", "123", "100");
        User uu = new User("魯班", "4600882", "123", "0");
        List<User> list = new ArrayList<>();
        list.add(u);
        list.add(uu);
        ATM atm = new ATM(list);//初始化資料 模擬
        Thread t = new Thread() {
            public void run() {
//                ATM atm = new ATM(list);
                for (int i = 0; i < 20; i++) {
                    atm.saveMoney("132466", "123", "12");
                    atm.delayTime(250);
                    atm.getMoney("4600882", "123", "14");
                    atm.delayTime(250);
                }
//                atm.balanceEnquiry("4600882", "123");
//                atm.balanceEnquiry("132466", "123");
            }
        };

        Thread tt = new Thread() {
            public void run() {
//                ATM atm = new ATM(list);
                for (int i = 0; i < 20; i++) {
                    atm.getMoney("132466", "123", "2");
                    atm.delayTime(250);
                    atm.saveMoney("4600882", "123", "12");
                    atm.delayTime(250);
                }
//                atm.balanceEnquiry("4600882", "123");
//                atm.balanceEnquiry("132466", "123");

            }
        };
        t.start();
        tt.start();
//        atm.balanceEnquiry("4600882", "123");
//        atm.balanceEnquiry("132466", "123");
    }
}

四、總結
(1)synchronized的使用:synchronized可以使用在方法上,也可以使用在程式碼塊上;如果我們需要用到不同的執行緒(多執行緒),注意synchronized(xxx.class){}、synchronized(this){} 後的效果;
(2)執行緒安全,簡單的理解:多執行緒執行程式碼的結果,要跟單流程執行程式碼的結果一樣;

相關推薦

Java 執行 模擬銀行ATM實時存取

近期想回顧一些知識: 一、Java 多執行緒 一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。多執行緒是多工的一種特別的形式,但多執行緒使用了更小的資源開銷。這裡定義和執行緒相關的另一個術

Java執行模擬售票系統

Java建立多執行緒的兩種基本方法:方法1.繼承Thread類(1)定義子類,繼承Thread類,重寫該類的run()方法作為執行緒執行體;(2)建立該子類的例項作為執行緒物件;(3)呼叫執行緒物件的start()方法來啟動執行緒;我們以模擬火車售票系統為例:public c

java執行模擬loadrunner進行壓測

package syttest; /** * @author yuzhuliu: * @version 建立時間:2017年9月26日 下午11:58:21 * 類說明 */ public

java執行入門案例(1)之簡單銀行取款問題及其優化

      之前學java的時候,學校老師由於課時問題,沒有教我們多執行緒,最近學校外聘的企業教師給我們做實訓要用到多執行緒,因此才初步瞭解多執行緒,以下這個案例只是介紹java程式碼優化,程式碼中有涉及多執行緒,但今天不對其講解,只簡單講解程式碼優化的問題,希望對初學

java:Map集合模擬鬥地主,執行模擬搶地主 例項

 原始碼如下: package selfpractice.day4; import java.util.*; //多執行緒模擬搶地,重點程式碼位於loot()方法內 public class Practice_Poker { public static void main(S

java執行程式設計--模擬龜兔賽跑過程

剛開始學多執行緒程式設計,課上也沒認真聽,課下去網上找了PPT,又認真的學了一遍。 問題: 編寫龜兔賽跑多執行緒程式,設賽跑長度為100米,每跑完10米輸出一次結果。 採用實現Runnable

java執行案例1之簡單銀行取款問題及其優化

      之前學java的時候,學校老師由於課時問題,沒有教我們多執行緒,最近學校外聘的企業教師給我們做實訓要用到多執行緒,因此才初步瞭解多執行緒,以下這個案例只是介紹java程式碼優化,程式碼中有涉及多執行緒,但今天不對其講解,只簡單講解程式碼優化的問題,希望對初學者有幫

JAVA學習之路(執行)---模擬售票(細解)

首先看題目描述: 假設有火車票100張,建立4個執行緒模擬4個售票點,每100ms售出一張,打印出售票過程,格式如下: 視窗3:賣出第100張票 視窗4:賣出第99張票  ............ ............ 簡單的思路就是建立一個類,首先肯定要去繼承Thread。開啟執行

Java執行同步---以銀行存取的過程的簡單程式碼例項

首先存錢取錢的這個操作,應該是執行緒操作的,可以有很多的顧客,這意思就是得有多個執行緒,多個執行緒之間共同操作一個銀行,銀行的金額就需要同步。才能保證執行緒安全。 所以,下面就把這個程式碼的例項放 這,有不對的地方,還請指出來哈。因為有個老鐵問這個多執行緒的程式碼。 首先是

java 執行基礎之銀行取號排隊系統

練習:銀行取號排隊 規則:銀行有四個視窗 1個vip視窗,只能接待vip顧客,另外三個視窗優先接待vip客戶 這裡對於執行緒的一些基礎介紹我就不累贅了 主要講講銀行排隊執行緒要注意哪些點? 1.肯定要寫一個客戶實體類,主要存放客戶的票號和客戶的種類(普通或VIP) 2

java執行經典問題二--銀行存錢問題

例項:兩個人向同一個賬戶裡面存錢 public class Demo { public static void main(String[] args) { //1.建立任務

Java執行場景模擬(1)

1.業務場景簡介     儲存使用者個人設定,一個使用者在a表中只能存在一條記錄,使用者修改記錄時,檢查如果該記錄存在,則修改該資料,如果該記錄不存在,則插入一條記錄。 2. 問題說明     多執行緒情況下,會出現一個使用者在表

Java執行簡單樣例(一):銀行存取問題

Bank類 public class Bank { private static int money; public int getMoney(){ return money; } public void saveMon

Java執行模擬一個阻塞佇列

import java.util.LinkedList; import java.util.concurrent.atomic.AtomicInteger; public class MyQueue { private final LinkedLi

JAVA執行_Process 模擬命令列視窗

JAVA多執行緒_Process 模擬命令列視窗 package com.hp.shell; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import j

java執行操作例子-(以銀行存錢取為例)

     以前一直沒有養成一個梳理知識的習慣,今天覆習到多執行緒的知識的,想到的經典的存錢取錢多執行緒同步機制,今天在這裡梳理下,錯的地方請各位大佬指正1:多執行緒同步的方法1:使用synchronized關鍵字修飾方法和程式碼塊(這就是兩種了)2:使用特殊變數volatit

Java執行實現電影院售票案例

某電影院目前正在上映賀歲大片,共有100張票,而它有3個售票視窗,請設計一個程式模擬該電影院售票。 定義Sell類實現Runnable介面,很好的解決了單繼承共享資源問題 public class Sell implements Runnable { // 定義100張票,三個售票

java執行物件鎖、類鎖、同步機制詳解

1.在java多執行緒程式設計中物件鎖、類鎖、同步機制synchronized詳解:     物件鎖:在java中每個物件都有一個唯一的鎖,物件鎖用於物件例項方法或者一個物件例項上面的。     類鎖:是用於一個類靜態方法或者class物件的,一個

Java 執行實現死鎖場景

簡述: 《Java 程式設計思想》  P718 ~ P722 模擬死鎖的場景, 三個人 三根筷子,每個人需要拿到身邊的兩根筷子才能開始吃飯 出現死鎖的場景是,三個人都拿到了右邊的筷子,但是由於筷子都被搶佔,均無法獲得左邊的筷子 Chopstick.java