我被要求创建一个Player类(实现runnable),其中我实现了一个生成随机数的run方法,并等待方法getchoice和getchoice方法,该方法返回生成的数字并通知run。然后是一个RockPaperScissors类(实现Runnable),其中包含方法运行,其中包含两个包含每个玩家对象的线程,这两个线程应该相互对战1000次,然后它们应该被中断然后它将显示每个玩家多少次赢了。 。我的问题是,当我的代码开始运行时,在开始时它是完美的,但是在一个随机的轮次中,它开始只玩了多次玩家1,然后进入玩家2,这违背了游戏的目的:这里是代码:
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;
}
}
}
如果我的程序运行完美,计数器显示应始终从0到1000一个接一个地重复,但在这里它开始像那样然后它搞砸了它永远不会达到1000,它有时停在700有时在800。我被允许使用的是notify(),notifyAll(),wait(),start(),interrupt()和join()。
非常感谢您的帮助。谢谢
答案 0 :(得分:1)
我会考虑使用semaphore或CountDownLatch来实现您的逻辑,以实现更好的同步
http://tutorials.jenkov.com/java-util-concurrent/semaphore.html
http://tutorials.jenkov.com/java-util-concurrent/countdownlatch.html
答案 1 :(得分:1)
您的实施和方法表明您不了解并发性,工作原理以及何时应用。
我建议你阅读Bruce Eckel撰写的相应章节(并发)&#34; Thinking in Java&#34; - http://www.mindview.net/Books/TIJ/
使你的代码工作你必须在Player.getChoise()返回之前再添加一个wait-notify
这是固定版本:
<强> 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());
}
}
<强> 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;
}