java同步

public class TransferRunnable implements Runnable {

public TransferRunnable(Bank b,int from,double max){
	
	bank = b;
	fromAccount = from;
	maxAmount = max;
}

public void run(){
	
	while(true){
		//fromAccount =1,2,3,4,5
		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) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
private Bank bank;
private int fromAccount;
private double maxAmount;
private int DELAY =10;

}

package com.trx.demothread;

public class UnsynchBankTest {

/**
 * @param args
 */
public static void main(String[] args) {
	// TODO Auto-generated method stub

	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();
	}
}

public static final int NACCOUNTS = 100;
public static final double INITIAL_BALANCE=1000;
}

详解竞争条件
几个线程更新银行账户余额。一段时间后,错误不知不觉地出现了,总额要么增加,要么变少。当两个线程试图同时更新同一个账户的时候,这个问题就出现了。假定两个线程同时执行指令
accounts[to] + = amount;
问题在于这不是原子操作。该指令可能被处理如下:
1)将accounts[0]加载到寄存器。
2)增加amount.
3)将结果写回accounts[to]。
现在,假定第一个线程执行步骤1和2,然后,它被剥夺了运行权。假定第二个线程被唤醒并修改了accounts数组中的同一项。然后,第一个线程被唤醒并完成其第3步。
这样,这一动作擦去了第二个线程所做的更新。于是,总金额不在正确。
加入synchronized或 Lock
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Bank {

private Lock bankLock = new ReentrantLock();
private Object o = new Object();
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){

// synchronized(o){
try{
bankLock.lock();

		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();
		}

// }

}

public double getTotalBalance(){
	double sum=0;
	for(double a:accounts)
		sum+=a;
	return sum;
}

public int size(){
	
	return accounts.length;
}

private final double[] accounts;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值