`

JAVA多线程小例:使用多线程实现银行转帐(未同步与同步)

 
阅读更多

使用多线程模拟实现银行转帐功能,先看看未使用同步的代码:

 

 

package com.test.current;

public class UnsynchBankTest {
	public static final int NACCOUNTS = 100;//帐户数
	public static final double INITIAL_BALANCE = 1000;//初始金额
	public static void main(String[] args) {
		Bank b = new Bank(NACCOUNTS, INITIAL_BALANCE);
		int i;
		for (i = 0; i < NACCOUNTS; i++) {
			TransferRunnable r = new TransferRunnable(b, i, INITIAL_BALANCE);
			Thread t = new Thread(r);
			t.start();
		}
	}

}
class Bank{
	private final double[] accounts;
	//initialBalance 初始金额
	public Bank(int n,double initialBalance) {
		accounts = new double[n];
		for (int i = 0; i < accounts.length; i++) {
			accounts[i] = initialBalance;
		}
	}
	//转帐
	public void transfer(int from ,int to ,double amount){
		if(accounts[from] < amount){ //金额不够
			return;
		}
		System.out.print(Thread.currentThread());
		accounts[from] -= amount;
		System.out.printf(" %10.2f from %d to %d",amount,from,to);
		accounts[to] += amount;
		System.out.printf(" Total balance %10.2f%n",getTotalBalance());
	}
	
	public double getTotalBalance(){
		double sum = 0;
		for (double a : accounts) {
			sum += a;
		}
		return sum;
	}
	
	public int size(){
		return accounts.length;
	}
}

class TransferRunnable implements Runnable{
	private Bank bank;
	private int fromAccount;
	private double maxAmount;//最大转帐金额
	private int DELAY =10;

	public TransferRunnable(Bank b, int from, double max) {
		bank = b;
		fromAccount = from;
		maxAmount = max;
	}
	public void run() {
		int toAccount = (int)(bank.size() * Math.random());
		double amount = maxAmount * Math.random();
		bank.transfer(fromAccount, toAccount, amount);
		try {
			Thread.sleep((int)(DELAY * Math.random()));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}

 最后打印的结果

 

 

由于 transfer方法中的accounts[to] += amount;操作是非原子的

指令可能会按下面的步骤执行

1,将accounts[to]载入寄存器

2,增加amount

3,将结果写回accounts[to]

 

假设某个线程执行了第1,2步后被中断,另一个线程对同一个位置的数组执行了1,2,3步,这时之前被中断的线程被唤醒了,执行了第3步,那么前一个线程的所做的更新就被抹去了。结果导致总金额不对。

 

二,使用ReentrantLock锁来保持同步

 

//转帐
	public void transfer(int from ,int to ,double amount){
		bankLock.lock();
		try{
			if(accounts[from] < amount){ //金额不够
				return;
			}
			System.out.print(Thread.currentThread());
			accounts[from] -= amount;
			System.out.printf(" %10.2f from %d to %d",amount,from,to);
			accounts[to] += amount;
			System.out.printf(" Total balance %10.2f%n",getTotalBalance());
		}finally{
			bankLock.unlock();
		}
	}//转帐
使用	synchronized 也可以实现同步
public synchronized void transfer(int from ,int to ,double amount){
		if(accounts[from] < amount){ //金额不够
			return;
		}
		System.out.print(Thread.currentThread());
		accounts[from] -= amount;
		System.out.printf(" %10.2f from %d to %d",amount,from,to);
		accounts[to] += amount;
		System.out.printf(" Total balance %10.2f%n",getTotalBalance());
	}
分享到:
评论

相关推荐

    java多线程模拟处理银行的实时转账交易

    本项目"java多线程模拟处理银行的实时转账交易"旨在通过多线程技术来模拟实现这一过程,确保程序的可扩展性和高效率。 首先,我们需要理解多线程的基本概念。线程是操作系统分配CPU时间片的基本单位,一个进程中...

    java多线程经典案例

    本案例将深入探讨Java多线程中的关键知识点,包括线程同步、线程通信和线程阻塞。 线程同步是为了防止多个线程同时访问共享资源,导致数据不一致。Java提供了多种同步机制,如synchronized关键字、Lock接口...

    操作系统实验 多线程同步与互斥 java编写 有界面

    5. **条件变量(Condition)**:与ReentrantLock一起使用,可以创建多个独立的等待队列,从而实现更复杂的同步策略。 6. **volatile关键字**:另一种防止数据不一致性的手段,它确保了对volatile变量的修改对所有...

    java 多线程同步方法的实例

    在Java编程语言中,多...同时,理解并掌握这些同步机制的原理和使用场景,对于提升Java多线程编程的能力至关重要。在实际开发中,要特别注意死锁、活锁和饥饿等问题,避免因线程同步不当而导致的性能下降或程序错误。

    java 银行系统多线程

    在Java编程中,银行系统是一个典型的多线程应用案例,因为银行系统中涉及多个并发操作,如存款、取款、转账等,这些操作通常需要在不同的线程中并行执行以提高效率。以下是对"java银行系统多线程"这个主题的详细说明...

    java多线程、锁的教程跟案例

    Java多线程与锁是Java并发编程中的核心概念,它们对于构建高效、可扩展的并发应用程序至关重要。在Java中,多线程允许程序同时执行多个任务,提高CPU的利用率,而锁则是用来控制多线程间共享资源的访问,确保数据的...

    JAVA多线程的一个带UI界面的例子

    在Java编程中,多线程是一项关键特性,...总之,这个"JAVA多线程的一个带UI界面的例子"涵盖了Java多线程编程和GUI设计的核心概念,通过实际的代码示例,有助于开发者深入理解如何在实际应用中正确、高效地使用多线程。

    最好的java多线程电子书

    ### 最好的Java多线程电子书 #### 一、并发与多任务 - **并发**:指在同一时间段内,系统能够处理多个任务的能力。在计算机领域中,这意味着多个任务看起来像是同时进行的,但实际上可能是通过快速切换的方式实现...

    java多线程的应用事例

    Java多线程是Java编程中的重要概念,尤其在开发高效能和并发应用程序时不可或缺。本文将深入探讨Java多线程的应用实例,这对于初学者来说是一个很好的学习起点。 首先,我们来看"SimulateRailwayStation.java"这个...

    java面试题之多线程

    在Java多线程编程中,面试题常常涉及到线程的基本概念、同步与异步的区别、线程同步方法以及Java提供的并发工具类。下面我们将深入探讨这些知识点。 1. **线程间的协作**: - `sleep()` 和 `wait()` 的区别:`...

    安全的编写多线程的_Java_应用程序

    ### 安全编写多线程Java应用程序的关键知识点 #### 一、引言 在现代软件开发中,多线程编程已成为提升程序性能和响应性的关键手段之一。Java作为一种广泛使用的编程语言,提供了丰富的多线程支持。然而,多线程...

    java课程设计 多线程设计 内含源代码 打包发布

    Java课程设计中的多线程设计是一项重要的编程技能,它涉及到并发执行、资源共享、同步机制等多个核心概念。在Java中,多线程允许程序同时执行多个不同的任务,极大地提高了程序的效率和响应速度。本课程设计的重点是...

    java多线程

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,极大地提升了程序的效率和响应性。在Java中,多线程主要通过两种方式实现:继承Thread类和实现Runnable接口。下面将深入探讨Java多线程的底层原理、...

    java多线程设计模式详解.rar

    Java多线程设计模式是Java开发中不可或缺的一部分,它涉及到并发编程的核心概念和技术。在Java中,多线程可以提高程序的执行效率,使多个任务能够同时运行,从而充分利用CPU资源。本文将深入探讨Java多线程设计模式...

    Java多线程学习总结.pdf

    线程同步是Java多线程中的重要概念,用于解决线程间的数据竞争问题。Java提供了多种同步机制,如`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`方法、`Lock`接口以及相关的`ReentrantLock`、`Semaphore...

    同步机制(JAVA)

    **同步机制在JAVA中的应用与实现** 在计算机科学领域,特别是在多线程编程中,同步机制扮演着至关重要的角色。操作系统课程设计中,理解和实践这一概念对于计算机专业的学生来说是必要的。本报告将深入探讨Java语言...

    Java多线程和并发知识整理

    Java多线程和并发知识是Java开发中的重要组成部分,它涉及到如何高效地利用系统资源,尤其是在多核CPU环境下,合理地使用多线程可以显著提升应用程序的性能。 **1. 理论基础** 1.1 为什么需要多线程 多线程的引入...

    Java 多线程与并发-Java并发知识体系详解.pdf

    Java并发编程是Java开发中的重要领域,涉及到多线程、并发控制、同步机制等多个知识点。以下是对Java并发知识体系的详细解析。 首先,我们要理解并发的理论基础。并发是为了提高系统资源利用率和处理能力,让多个...

    同步块线程的调用--java

    在Java编程语言中,线程同步是多线程编程中的一个重要概念,用于解决并发执行时可能出现的数据不一致性问题。同步可以确保多个线程在访问共享资源时按照特定的顺序进行,防止数据竞争和死锁等问题的发生。本篇将深入...

    JAVA多线程——一篇文章让你彻底征服多线程开发.docx

    ### JAVA多线程详解 #### 一、线程与进程的概念 在计算机科学中,**进程**是指一个正在运行的应用程序或程序实例,而**线程**则是进程中可并发执行的一部分,是进程内的一个执行流。一个进程可以拥有多个线程,这些...

Global site tag (gtag.js) - Google Analytics