2017-01-29 1 views
-1

랜덤 넘버를 생성하고 getchoice 메소드와 생성 된 숫자를 반환하고 실행을 알리는 getchoice 메소드를 기다리는 run 메소드를 구현하는 Player 클래스 (runnable을 구현하는 클래스)를 만들도록 요청받습니다. 다음에, 각각의 player object를 포함한 2 개의 thread를 포함하는 메소드의 실행을 포함한 RockPaperScissors 클래스 (Runnable를 구현하고있다)는,이 2 개의 thread는 서로 1000 회 재생해야합니다. 그 후, 중단되고 나서, 각 player가 몇 회 표시되는지를 나타냅니다 원 . . 내 문제는, 내 코드가 실행되기 시작하면 처음에는 완벽하지만 무작위 라운드에서는 게임의 목적을 상실한 플레이어 2에게 가기 전에 여러 번 플레이어 1을 재생하기 시작합니다. 코드는 다음과 같습니다.두 스레드를 주기적으로 실행하는 방법은 무엇입니까?

public class RockPaperScissors implements Runnable { 
int result1 ; 
int result2 ; 
int result3 ; 

private final Object lock = new Object(); 

public void run(){ 


    synchronized(lock){ 
     Player a = new Player() ; 
     Player b = new Player() ; 
    Thread a1 = new Thread(a) ; 
    Thread b1= new Thread (b) ; 
     a1.start(); 
     b1.start(); 
     int choice1 = -100 ; 
    int choice2 = -1066 ; 
    for (int i = 0 ; i < 1000 ; i++){ 



    try { 

     choice1 = a.getChoice();  
    } catch (InterruptedException e1) { 

    } 


    try { 

     choice2 = b.getChoice(); 

    } catch (InterruptedException e) { 

    } 
    if (choice1 == 1 && choice2==0) 
     result2++; 
    else if (choice2 == 1 && choice1==0) 
     result1++; 
    else if (choice1 == 1 && choice2==1) 
     result3++ ; 
    else if (choice1 == 1 && choice2==2) 
     result1++ ; 
    else if (choice1 == 2 && choice2==1) 
     result2++ ; 
    else if (choice1 == 0 && choice2==2) 
     result1++ ; 
    else if (choice1 == 2 && choice2==0) 
     result2++ ; 
    else if (choice1 == 2 && choice2==2) 
     result3++ ; 
    else if (choice1 == 0 && choice2==0) 
     result3++ ; 


    } 

이 클래스의 플레이어입니다 :

public class Player implements Runnable { 
private final Object lockvalue = new Object(); 
private int a; 

public void run() { 
    synchronized (lockvalue) { 
     for (int counter = 0; counter < 1000; counter++) { 

      java.util.Random b = new java.util.Random(); 
      a = b.nextInt(3); 
      System.out.println(counter); 
      try { 
       lockvalue.wait(); 
      } catch (InterruptedException e) { 
       System.out.println("Thread player was interrupted"); 

      } 

     } 

    } 
} 

public int getChoice() throws InterruptedException { 
    synchronized (lockvalue) { 
     lockvalue.notify(); 
     return a; 

    } 

} 

}

내 programm에 완벽하게 카운터 디스플레이는 항상 1000 0에서 시작하는 번호가 있어야 실행하는 경우

다른 후 하나를 복제하지만, 여기에 그것처럼 시작하지만 그때 그것은 엉망이된다. 1000에 이르지 못한다. 때로는 700에서 때때로 800으로 멈춘다. 내가 사용하도록 허용 된 것은 notify(), notifyAll(), wait(), start(), interrupt() 및 join()입니다.

도움을 주시면 대단히 감사하겠습니다. 감사합니다

+0

Runnable 오브젝트는이 뛴하지 얼마나 많은 시간을 게임을 승리 사용자에 대한 정보가 있어야합니다. – duffymo

+0

RockPaperScissors의 실행 파일을 의미합니까? – Domarius

+1

예. 내가 너라면, 두 선수가 완벽하게 작동하는 게임의 논리가 나올 때까지 스레드에 대해 잊어 버릴 것이다. 일단 그렇게하면 다중 스레드로 만듭니다. – duffymo

답변

1

당신의 당신이 어떻게 작동하는지, 동시성을 이해하지 못하는 구현 및 접근 쇼 그리고 언제 적용되어야하는지.) (당신은 Player.getChoise에 반환하기 전에 대기가-통지 하나 더 추가해야 당신의 코드가 작동하려면 http://www.mindview.net/Books/TIJ/

-

는 당신이 브루스 에켈 (Bruce Eckel)의 "자바 생각"에 해당하는 장 (동시성)을 읽는 것이 좋습니다

RockPaperScissors.java

package game; 

public class RockPaperScissors 
{ 
    static int player1wins = 0; 
    static int player2wins = 0; 
    static int draw = 0; 

    public static void main(String[] args) throws InterruptedException 
    { 
    int cycles = 1000; 
    Player player1 = new Player("Player-1", cycles); 
    Player player2 = new Player("Player-2", cycles); 

    new Thread(player1).start(); 
    new Thread(player2).start(); 


    for (int i = 0; i < cycles; i++) 
    { 
     Choice choice1; 
     Choice choice2; 

     choice1 = player1.getChoice(); 
     System.out.println("Value 1 is definitely generated"); 

     choice2 = player2.getChoice(); 
     System.out.println("Value 2 is definitely generated"); 

     System.out.printf("\n%3d\nPlayer1 - %8s\nPlayer2 - %8s\n", i, choice1.name(), choice2.name()); 

     if (choice1 == choice2) 
     { 
     draw++; 
     System.out.println("Draw!"); 
     } 
     else if (choice1 == Choice.ROCK) 
     { 
     if (choice2 == Choice.PAPER) 
     { 
      player2wins++; 
      System.out.println("2 wins!"); 
     } 
     else 
     { 
      player1wins++; 
      System.out.println("1 wins!"); 
     } 
     } 
     else if (choice1 == Choice.PAPER) 
     { 
     if (choice2 == Choice.SCISSORS) 
     { 
      player2wins++; 
      System.out.println("2 wins!"); 
     } 
     else 
     { 
      player1wins++; 
      System.out.println("1 wins!"); 
     } 
     } 
     else if (choice1 == Choice.SCISSORS) 
     { 
     if (choice2 == Choice.ROCK) 
     { 
      player2wins++; 
      System.out.println("2 wins!"); 
     } 
     else 
     { 
      player1wins++; 
      System.out.println("1 wins!"); 
     } 
     } 
    } 
    System.out.printf("Player 1 wins - %3d times;\n" + 
     "Player 2 wins - %3d times;\n" + 
     "Draw result - %3d times\n\n", player1wins, player2wins, draw); 

    System.out.printf("Player-1 cycles left = %d\n" + 
     "Player-2 cycles left = %d\n", player1.getCounter(), player2.getCounter()); 
    } 
} 
,536 : 여기

고정 버전

Player.java

package game; 

import java.util.Random; 

public class Player implements Runnable 
{ 
    private Random random = new Random(); 
    private int value; 
    private int counter; 
    private String name; 

    public Player(String name, int cycles) 
    { 
    this.name = name; 
    this.counter = cycles; 
    } 

    public synchronized void run() 
    { 
    while (true) 
    { 
     try 
     { 
     wait(); 
     } 
     catch (InterruptedException e) 
     { 
     e.printStackTrace(); 
     } 

     value = random.nextInt(3); 
     System.out.println(name + " ... Value was generated = " + value); 
     notify(); 

     // Otherwise your thread will never stop! 
     counter--; 
     if (counter <= 0) 
     { 
     System.out.println(name + " ... Limit of operations is exceeded."); 
     break; 
     } 
    } 
    } 

    public synchronized Choice getChoice() throws InterruptedException 
    { 
    System.out.println(name + " ... now can generate value"); 
    notify(); 
    System.out.println(name + " ... wait until value is generated"); 
    wait(); 
    Choice choice = Choice.values()[value]; 
    System.out.println(name + " ... returning generated value: " + value); 
    return choice; 
    } 

    public int getCounter() 
    { 
    return counter; 
    } 
} 

Choise.java는

package game; 

public enum Choice 
{ 
    ROCK, 
    PAPER, 
    SCISSORS; 
} 
+0

대단히 감사합니다. 정확히 내가 무엇을 찾고 있었는지. 실행 중에 while (true) wait() 루프를 수행해야하는 이유는 무엇입니까? 왜 내가 getchoice에서 기다려야합니까? – Domarius

+0

while 루프는 카운터 때문에 for 루프와 동일한 작업을 수행하지만 내 관점에서는보다 논리적으로 보입니다. wait()는 모니터를 해제하고 getChoice를 중지하고 run()이 실행되도록하기 위해 getChoice가 wait 다음 임의의 값 생성에 필요합니다. 당신은 그것을 주석 처리하고 어떤 일이 일어날지를 볼 수 있습니다. 그래서 나는 간단한 로그 메시지를 추가했습니다. – sergpank

관련 문제