2017-12-11 10 views
-3

나는 수업을 위해 할 일이 주어졌지만 우리는 어느 정도 가르쳐 왔지만 이것은 지식 격차를 남겼다. 우리는 수업에서했던 일부 코드를 완성하도록 요청 받았고, 교사는 어떻게해야하는지에 대한 설명을 주었지만, 마지막으로 독립 자바 작업을 한 지 약 7 개월이 지났습니다. 아래의 약간 녹슬지 않는 부분은 교사지도와 함께 작성한 코드이며, 과제에 대한 설명 아래에 나와 있습니다. 이클립스 실행 설정에 포함동시 프로그래밍 자바 스레드

public class CardHolder implements Runnable { 
private int id; 
private Account account; 
final static int numIterations = 20; 

public CardHolder(int id, Account account) { 
    this.id = id; 
    this.account = account; 
} 

/* 
* run method is what is executed when you start a Thread that 
* is initialised with an instance of this class. 
* You will need to add code to keep track of local balance (cash 
* in hand) and report this when the thread completes. 
*/ 
public void run() { 
    for (int i = 0; i < numIterations; i++) { 
     // Generate a random amount from 1-10 
     int amount = (int)(Math.random()*10)+1; 
     // Then with 50/50 chance, either deposit or withdraw it 
     if (Math.random() > 0.5) { 
      account.withdraw(id, amount); 
     } else { 
      account.deposit(id, amount); 
     } 
     try { 
      Thread.sleep(200); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    System.out.println("THREAD "+ id + " finished"); 

} 
} 

import java.util.ArrayList; 

public class Account { 
private String name; 

/** 
* @param args 
*/ 
public static void main(String[] args) { 
    // Check to make sure program has been called with correct number of 
    // command line arguments 
    if (args.length != 3) { 
     System.err.println("Error: program should take exactly three command line arguments:"); 
     System.err.println("\t<No. of accounts> <main acct starting bal.> <backup acct. starting bal.>"); 
     System.exit(0); 
    } 
    // And then make sure that those args are all integers 
    try { 
     int numCards = Integer.parseInt(args[0]); 
     Account account = new Account("Main", Integer.parseInt(args[1])); 
     Account backup = new Account("Backup", Integer.parseInt(args[2])); 

     // Your code to create and manage the threads should go here. 
    } catch (NumberFormatException e) { 
     System.err.println("All three arguments should be integers"); 
     System.err.println("\t<No. of accounts> <main acct starting bal.> <backup acct. starting bal.>"); 
    } 
} 

// Create an account - initalisation goes in here 
public Account(String name, int startingBalance) { 
} 

// Deposit <amount> into the account 
public void deposit(int id, int amount) { 
} 

// Withdraw <amount> from the account 
public void withdraw(int id, int amount) { 
} 

// Print out the statement of transactions 
public void printStatement() { 
    System.out.println("Account \"" + name + "\":"); 
} 
} 

인수는 50 1000 1000

작업이

대부분의 은행 시스템은 여러 카드 소지자가 하나의 계정에 액세스 할 수 있습니다 (예를 들어 비즈니스
계정입니다). 이 결과로 한 명 이상의 사람이 동시에 단일 계좌에서 돈을 인출하거나 입금하려고 시도 할 수 있습니다. 계정에 대한 액세스가 순조롭게 (동시 프로그래밍 원칙을 무시하고) 구현 된 경우이
은 경쟁 조건으로 이어질 수 있으며 다음과 같은 사기가 성공할 수있는 가능성이 있습니다. 복수 카드 소지자가 공모하여 타이밍 공격. 그러한
공격에서 여러 명의 카드 소지자가 계좌 잔고를 동시에 공제하기 위해 과 동시에 계좌에서 금액을 인출합니다. 당신의 임무는 복수의 연결된 카드가있는 ATM 가능 연결된 은행 계좌의 작동을 시뮬레이션하는 프로그램 (아래의 세부 사양)을 작성하는 것입니다. 즉,
각 계정에 액세스 할 수있는 여러 명의 개인이 있으며 각자 자신의 카드()가 있습니다. 당신의 프로그램이 성공하기 위의 사기가
불가능하고, 동시 프로그래밍의 원리를 설명한다

어떤 도움을 크게

감사

+2

[실제 질문이 아닌 이유는 무엇입니까?] (http://meta.stackoverflow.com/q/284236) –

+0

교과서의 장을 다시 읽어야 할 것처럼 보입니다. '자물쇠' – shinjw

답변

1

좋아, 당신이 필요로하는 중요한 것은 감사하겠습니다 걱정하지 않으려면 예금 및 인출 방법입니다. 예를 들면 다음과 같습니다.

public class Account { 
    public void deposit(int id, int amount) { 
     balance += amount; 
    } 

    public void withdraw(int id, int amount) { 
     balance -= amount; 
    } 

    private int balance; 
} 

이 문제는 증가/감소 작업이 원자적일 수 없다는 점에서 문제가 있습니다. 후드 아래에는 여러 가지 작업이있을 수 있습니다. 예 :

int temp1 = balance; 
int temp2 = amount; 
int temp3 = temp1 - temp2; 
balance = temp3; 

이 작업을 동시에 수행하는 스레드가 많은 경우 원하지 않는 결과가 발생할 수 있습니다. 이유에 대해 생각해보십시오. 동기화 된 키워드 인 을 사용하면 전체 메서드가 자동으로 실행되도록 할 수 있습니다.

public class Account { 
    public synchronized void deposit(int id, int amount) { 
     balance += amount; 
    } 

    public synchronized void withdraw(int id, int amount) { 
     balance -= amount; 
    } 

    private int balance; 
} 

이를 테스트하기 위해, 나는 랜덤를 사용하지 것이다, 그것은 결정하지 않기 때문에 : 내가 그것을하지 생각하는 것은 뮤텍스에 클래스의 인스턴스를 켭니다. 내가 할 일은 1000 개의 쓰레드를 동시에 실행하여 특정 수의 인출을 동시에 수행하는 것입니다. $ 1,000,000의 잔액이 있고 1000 개의 스레드를 실행하여 $ 1을 초과하여 1000 번 이상 철회 한 경우 테스트 후에 계정에 $ 0이 있어야합니다.synchronized 키워드를 추가하기 전에 오답을 시뮬레이션 해보고 synchronized 키워드를 추가하여 수정되었는지 확인하십시오.