Java多线程共享数据问题
两个人分别用银行卡, 存折同时取钱,
以下是代码,并执行:
public class Test implements Runnable{
?private int account=10;;
?public static void main(String[] args) {
??
? Test t=new Test();
? Thread one=new Thread(t);
? Thread two=new Thread(t);
? one.setName("guolei ");
? two.setName("yunhui ");
? one.start();
? two.start();
?}
?
?@Override
?public void run() {
? // TODO Auto-generated method stub
? for(int x=0;x<1;x++){
? ?makeWithdrawal(10);
? ?
? }
?}
?private void makeWithdrawal(int amount){
??
? if(account>=amount){
? ?
? ?System.out.println(Thread.currentThread().getName()+"is about to withdraw ? ? ?"+account);
? ?try {
? ? System.out.println(Thread.currentThread().getName()+"is going to sleep ? ? ? ? "+account);
? ? Thread.sleep(500);
? ?} catch (InterruptedException e) {
? ? // TODO Auto-generated catch block
? ? e.printStackTrace();
? ?}
? ?System.out.println(Thread.currentThread().getName()+"wake up ? ? ?"+account);
? ?account-=10;
? ?System.out.println(Thread.currentThread().getName()+"complete ? ? ? ? "+account);
? }
? else{
? ?System.out.println("sorry ? "+Thread.currentThread().getName());
? }
?}
?
?
}
执行结果:guolei is about to withdraw ? ? ?10
? ?guolei is going to sleep ? ? ? ? 10
? ?yunhui is about to withdraw ? ? ?10
? ?yunhui is going to sleep ? ? ? ? 10
? ?guolei wake up ? ? ? ? ? 10
? ?guolei complete ? ? ? ? ? ? ? ? ?0
? ?yunhui wake up ? ? ? ? ? ? ? ? ? 0
? ?yunhui complete ? ? ? ? ? ? ? ? -10
结果当yunhui去完钱的时候已经透支了,如何避免这种透支的情况了?我们必须要确保线程一旦进入makeWithdrawal()方法之后,他就必须能够在其他线程
进入之前把任务执行完毕。什么意思了?也就是说我们需要确保线程一旦开始检查检查账户余额,就要能够确定它在其他线程检查余额之前醒来把提款动作
完成。
使用synchronized这个关键词修饰方法可以使它每次只能被单一的线程存取。将此关键字加到方法之后结果就是:
guolei is about to withdraw ? ? ?10
guolei is going to sleep ? ? ? ? 10
guolei wake up ? ? ?10
guolei complete ? ? ? ? 0
sorry ? ? yunhui
?