如何定期运行两个线程?

时间:2017-01-29 14:18:00

标签: java multithreading java-threads

我被要求创建一个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()。

非常感谢您的帮助。谢谢

2 个答案:

答案 0 :(得分:1)

答案 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;
}