2015-01-12 1 views
-2

자바 멀티 스레딩을 배우고 있습니다. 이것은 내가 작성한 코드입니다.자바가 변수를 보호하지 않고 동기화되었습니다

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() + " You 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()에서 키워드 동기화 넣어. 그러나 여전히 나는 부정적 균형을 얻습니다.

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 

내가 뭘 잘못 했니?

+3

기록을 동기화해야하지 않습니까? –

+1

참고로, money와 같은 중요한 중요 값에는'double'을 사용하지 마십시오. –

+0

Juan이 언급했듯이 get을 동기화하는 대신 쓰기 작업을 동기화해야합니다. 동기화 할 때 사용할 필요가 없습니다. getBalance – Wael

답변

3

나는 의 철수를 동기화해야한다고 생각합니다.

코드에서 방금 두 개의 스레드가 동시에 철회 할 수 있지만 동시에 균형을 확인할 수는 없습니다.

는 당신은 한 번에 균형을 확인 & 하나 스레드를 철회 하나 스레드를 원한다.

(수정 제안 사항 주신)

+2

둘 모두를 동기화해야합니다. –

+2

및'setBalance' too – talex

+0

@MarkRotteveel - 나는 두 번째입니다. 그는 getter와 setter 모두에서 동기화해야합니다. – TheLostMind

관련 문제