Java同步不保护变量

时间:2015-01-12 13:45:29

标签: java multithreading

我正在学习Java多线程。这是我写的代码。

package com.company;


public class Account  {
    private double balance = 100;

    public synchronized double getBalance() {
        synchronized (this){
            return balance;
        }
    }

    public  void setBalance(double balance) {
        this.balance = balance;
    }
    public   boolean withdraw(double amount,String name){
        if(this.getBalance()>amount){
            if(Thread.currentThread().getName().equals("customer0")){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.setBalance(this.getBalance() - amount);
            System.out.println(Thread.currentThread().getName() + " withdraw " + amount);
            System.out.println("Hello,  " + Thread.currentThread().getName() + " You current balance is " + this.getBalance());

            return true;
        }
        else{
            System.out.println("Sorry, " + Thread.currentThread().getName() + ". Your current balance is " + this.getBalance() + " and you  cannot withdraw " + amount);
            //System.out.println("Welcome,  " + Thread.currentThread().getName() + " Your current balance is " + this.getBalance());

            return false;
        }
    }
}

和主要课程

package com.company;

import org.omg.PortableServer.THREAD_POLICY_ID;


public class Main implements Runnable {
    Account account = new Account();
    public static void main(String[] args){
            Main main = new Main();
            for(int i= 0; i< 2; i++) {
                Thread c1 = new Thread(main, "customer" + i);
                c1.start();
            }
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "'s balance is " + account.getBalance());
        account.withdraw(60, Thread.currentThread().getName());
        //
    }
}

我在getBalance()中放置了synchronized关键字,以确保一次只能访问一个线程。但我仍然得到负余额。

customer0's balance is 100.0
customer1's balance is 100.0
customer1 withdraw 60.0
Hello,  customer1 You current balance is 40.0
customer0 withdraw 60.0
Hello,  customer0 You current balance is -20.0

我做错了什么?

1 个答案:

答案 0 :(得分:3)

我认为您应该同步撤销余额。

您的代码现在可以让两个线程同时撤销,但不允许他们同时检查余额。

您只需一个主题撤销&amp; 一个线程一次检查余额。

(感谢您的编辑建议)