JAVA 多线程练习:转账案例

 

目录

一、题目

二、类图及其关系

三、详细步骤

1.取钱流程

2.转帐流程

四、代码

1.文本模拟数据库

2.取钱

3.转账

4.测试函数

5.测试结果


一、题目

 

二、类图及其关系

 

三、详细步骤

1.取钱流程


{1}设置同步监视代码块,监视对象: wang. txt
{2}获取老王余额
{3}判断帐户的余额是否足够。
{4}如果ok更新老王余额。不ok,提示余额不足(抛出异常)


2.转帐流程


{1}监视老李文件: li. txt
{2}获取老李的钱
{3}看看li帐户够不够钱
{4}余额不足判断不足--->抛出异常。
{5}计算老李余额: 5000-1600 = 3400
{6}监视老王文件: wang. txt
{7}获取老王的钱: 2500
{8}更新老王的钱:2500+1600=??
{9}更新老李的钱:3400

四、代码

1.文本模拟数据库

package com.gongsi.cn.test2;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;

//数据库操作类(文本)
public class MoneyDao {

	private String target;//li.txt wang.txt
	public MoneyDao(String target) {
		this.target=target;
	}
	
	
	//获取转账的余额
	public int getMoney() throws Exception {
		//获取要转账的txt的内容 文件输入流
		FileInputStream fis=new FileInputStream(target);
		byte[] buff =new byte[1024];
		int cnt=0;
		String msg;
		cnt=fis.read(buff);
		int yuer = 0;
		if (cnt>0) {
			msg=new String(buff,0,cnt);
			yuer=Integer.valueOf(msg);
			
			}
		return yuer;
		
	}
	
	//更新账户的余额 把余额写入目标帐户
	public void saveMoney(int money) throws Exception {
		PrintWriter pr = new PrintWriter(target);
		pr.print( money );
		pr.close();
//		//文件输出流
//		FileOutputStream fos=new FileOutputStream(target);
//		fos.write(money);
//		fos.close();
	}
	
//	//测试一下
//	public static void main(String[] args) throws Exception {
		MoneyDao moneyDao=new MoneyDao("C:\\a\\li.txt");
		int yuer=moneyDao.getMoney();
		System.out.println(yuer);
		moneyDao.saveMoney(500);
//		String wangTxt = "C:\\a\\li.txt";
//		String liTxt = "C:\\a\\wang.txt";
//		MoneyDao wangDao = new MoneyDao( wangTxt );
//		MoneyDao liDao = new MoneyDao( liTxt );
//		wangDao.saveMoney( 850 );//500
//		liDao.saveMoney( 1005 );//0
//		System.out.println("{ps}写入成功...");
//	}
}


2.取钱

package com.gongsi.cn.test2;

import java.io.IOException;



/*
 * 取钱任务
 *	2.1、类名称: DrawTask类
 *  2.2、主要实现取钱的功能。
 *  2.3、实现 Runnable 接口。
 *       实现  run() 方法。
*/
public class DrawTask implements Runnable {
	
	
	
	String target;// 目标账户
	int money;// 取多少钱
	MoneyDao moneyDao=new MoneyDao(target);// 操作数据库

	public DrawTask(String target, int money) {
		this.target = target;
		this.money = money;
		this.moneyDao = new MoneyDao(target);
	}

	public void draw() throws Exception {

		int yuer=0;
		
		synchronized (target) {
			yuer = moneyDao.getMoney();
			if (yuer< money) {
				throw new RuntimeException("余额不足 !!!");
			} 
			moneyDao.saveMoney(yuer - money);
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	@Override
	public void run() {
		try {
			System.out.println("ATM正在取钱......");

			draw();
			System.out.println("取钱成功,请带好您的钱离开");
		} catch (Exception e) {
			System.out.println("{ATM}取钱失败, 原因:" + e.getMessage());
		}

	}

}

3.转账

package com.gongsi.cn.test2;



/*
        转帐任务类
	3.1、类名称: TransferTask类
 *  3.2、实现 Runnable 接口
 *       实现 run() 方法。
*/
public class TransferTask implements Runnable{

	private String src;// 谁转的 源
	private String des;// 转去哪  目的
	private int money;//你要转多少钱出去
	MoneyDao desDao;
	MoneyDao srcDao;
	public TransferTask(String src,String des,int money) {
		this.src=src;
		this.des=des;
		this.money=money;
		srcDao = new MoneyDao( src );
		desDao = new MoneyDao( des );
	}

	public void transfer() throws Exception {
		int liMoney;
		int wangMoney;
		int remain;
		synchronized (srcDao) {
			//srcDao=new MoneyDao(src);
			liMoney=srcDao.getMoney();
			if (liMoney<money) {
				throw new Exception("您的余额不足!");
			}
			remain=liMoney-money;
			
			synchronized (desDao) {
				//desDao=new MoneyDao(des);
				wangMoney=desDao.getMoney();
				desDao.saveMoney(wangMoney+money);
			}
			srcDao.saveMoney(remain);
		}
	}
	@Override
	public void run() {
		try {
			System.out.println("ATM正在转账......");

			transfer();
			System.out.println("转账成功,请带好您的钱离开");
		} catch (Exception e) {
			System.out.println("{ATM}转账失败, 原因:" + e.getMessage());
		}

		
	}

}

4.测试函数

package com.gongsi.cn.test2;

public class Testmain {
	public static void main(String[] args) throws Exception {
		
	    //老王: 2500 - 300 = 2200(剩下) [取钱]
		
		//老李: 5000 - 600 = 4400	(剩下) [转账]	
		//老王: 2200 + 600 = 2800(剩下) [转账]
		String wantTxt = "C:\\a\\wang.txt";
		String liTxt   = "C:\\a\\li.txt";
		DrawTask dTask = new DrawTask(wantTxt, 300);
		TransferTask tTask = new TransferTask(liTxt,wantTxt, 600);
		
		Thread th1 = new Thread( dTask );
		Thread th2 = new Thread( tTask );
		
		th1.start();
		Thread.sleep( 10 );
		th2.start();
	}

}

5.测试结果

可在文本中看到数字的变化

这是用Java编写的一个简单的银行转账系统,包括取款,存款,转账等功能,其中用到了数据库的连接,采用Eclipse编写,包含数据库的设计文件。非常适合有一定基础的Java初学者使用。 package com.gujunjia.bank; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ import java.sql.*; /** * * @author gujunjia */ public class DataBase { static Connection conn; static PreparedStatement st; static ResultSet rs; /** * 加载驱动 */ public static void loadDriver() { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { System.out.println("加载驱动失败"); } } /** * 创建数据库的连接 * * @param database * 需要访问的数据库的名字 */ public static void connectionDatabase(String database) { try { String url = "jdbc:mysql://localhost:3306/" + database; String username = "root"; String password = "gujunjia"; conn = DriverManager.getConnection(url, username, password); } catch (SQLException e) { System.out.println(e.getMessage()); } } /** * 关闭数据库连接 */ public static void closeConnection() { if (rs != null) { // 关闭记录集 try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (st != null) { // 关闭声明 try { st.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { // 关闭连接对象 try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } package com.gujunjia.bank; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * 本类主要实现整个系统的界面 * * @author gujunjia */ public class MainFrame extends JFrame implements ActionListener, FocusListener { /** * */ private static final long serialVersionUID = 1L; public static String userId; JTextField userIdText; JPasswordField passwordText; JButton registerButton; JButton logInButton; public MainFrame() { super("个人银行系统"); this.setSize(400, 500); this.setLocation(getMidDimension(new Dimension(400, 500))); getAppearance(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } /** * 获取屏幕的中间尺寸 * * @param d * Dimension类型 * @return 一个Point类型的参数 */ public static Point getMidDimension(Dimension d) { Point p = new Point(); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); p.setLocation((dim.width - d.width) / 2, (dim.height - d.height) / 2); return p; } /** * 布局 * * @return Container */ public Container getAppearance() { Container container = this.getContentPane(); container.setLayout(new GridLayout(4, 0)); JLabel label1 = new JLabel("个人银行系统"); label1.setFont(new Font("楷体", Font.BOLD, 40)); JLabel label2 = new JLabel("账号"); label2.setFont(new Font("楷体", Font.PLAIN, 15)); JLabel label3 = new JLabel("密码"); label3.setFont(new Font("楷体", Font.PLAIN, 15)); userIdText = new JTextField(20); userIdText.addFocusListener(this); passwordText = new JPasswordField(20); passwordText.addFocusListener(this); JPanel jp1 = new JPanel(); JPanel jp2 = new JPanel(); JPanel jp3 = new JPanel(); JPanel jp4 = new JPanel(); jp1.add(label1); jp2.add(label2); jp2.add(userIdText); jp3.add(label3); jp3.add(passwordText); registerButton = new JButton("注册"); registerButton.addActionListener(this); registerButton.setFont(new Font("楷体", Font.BOLD, 15)); logInButton = new JButton("登录"); logInButton.addActionListener(this); logInButton.setFont(new Font("楷体", Font.BOLD, 15)); jp4.add(registerButton); jp4.add(logInButton); container.add(jp1); container.add(jp2); container.add(jp3); container.add(jp4); return container; } public void actionPerformed(ActionEvent e) { Object btn = e.getSource(); if (btn == registerButton) { new Register(); } else if (btn == logInButton) { String id = userIdText.getText().trim(); String password = new String(passwordText.getPassword()); Bank bank = new Bank(); if (id.equals("") || password.equals("")) { JOptionPane.showMessageDialog(null, "请输入账号和密码"); } else { String dPassword = bank.getPassword(id); if (password.equals(dPassword)) { userId = id; this.dispose(); new UserGUI(); } else { JOptionPane.showMessageDialog(this, "密码或用户名错误", "错误", JOptionPane.ERROR_MESSAGE); } } } } @Override public void focusGained(FocusEvent e) { Object text = e.getSource(); if (text == userIdText) { userIdText.setText(""); userIdText.setFont(new Font("宋体", Font.BOLD, 15)); } else if (text == passwordText) { passwordText.setText(""); } } @Override public void focusLost(FocusEvent e) { Object text = e.getSource(); if (text == userIdText) { if (userIdText.getText().equals("")) { userIdText.setText("请输入账号"); userIdText.setFont(new Font("楷体", Font.ITALIC, 15)); } } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

摆烂收留中心

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值