如何使线程按顺序打印java

时间:2013-12-07 22:38:41

标签: java multithreading

有些人可能早些时候已经看过这个代码,我继续介绍它,现在我遇到了空指针和indexOutOfBound异常的问题。索引出界的错误有时取决于玩家的数量或手的大小。

这是代码,主要的CardGame类

public class CardGame
{
   static Player[] players;
   static int handSize;
   static Queue<Card>[] playingDeckArray;
   static int playersNum;

   public static void main(String[] args){
        Scanner reader = new Scanner(System.in);

        System.out.println( "\nHello, how many players would you like" );
        playersNum = Integer.parseInt(Checks.userInputCheck( "\\d" ));
        System.out.println( "\nHow many cards should each player begin with" );
        int handSize = Integer.parseInt(Checks.userInputCheck( "\\d" ));
        System.out.println( "\nWhich strategy would you like to use 1 or 2" );
        int strategy = Integer.parseInt(Checks.userInputCheck( "[12]$" ));

        Logger.createDeck( playersNum, handSize );

        makePlayers( playersNum, handSize, strategy );

        makePlayingDecks( playersNum );

        dealInitialHand( playersNum, players, handSize );

        makePlayerOutputs();

        //Player.startPauseThread();

        for ( int i = 0; i < players.length; i++){
           logInitialHand(players[i]);
        }

        for ( int i = 0; i < players.length; i++){
           isWinner( players[i]);
        }

        for ( int i = 0; i < players.length; i++){
            new Thread(players[i]).start();
        }
   }

   private static void makePlayers(  int noPlayers, int noCardsInHand, int strategyChosen){
       players = new Player[noPlayers];
       for( int i = 0; i < noPlayers; i++){
           players[i] = new Player( strategyChosen, noCardsInHand, i+1 );
           players[i].fillHand();
       }

   }

   private static void dealInitialHand(int noPlayers, Player[] players, int noCardsInHand ){
       System.out.println( "\nPlease enter the name of the deck file" );
       File theDeck = new File (Checks.userInputCheck( "deckfile.txt" ) );

       int line = 0;

       try{
           Scanner fileScanner = new Scanner( theDeck );
           for( int h = 0; h < noCardsInHand; h++){
               for( int p = 0; p < noPlayers; p++){
                    line = Integer.parseInt( fileScanner.nextLine() );
                    players[p].setHand( line, h );
               }
           }

           for( int t = 0; t < noCardsInHand; t++){
               for( int i = 0; i < playingDeckArray.length; i++ ){
                   line = Integer.parseInt( fileScanner.nextLine() );
                   playingDeckArray[i].add( new Card(line) );
                }
               }

            }catch (Exception e) {
           e.printStackTrace();
       }

       seePlayerHands();
   }

   private static void makePlayingDecks( int noPlayers ){
       playingDeckArray = new Queue[noPlayers];
       for( int i = 0; i < playingDeckArray.length; i++ ){
           playingDeckArray[i] = new ConcurrentLinkedQueue<Card>();
           System.out.println( playingDeckArray[i] );
        }

   }

   private static void seePlayerHands(){
       for ( int i = 0; i < players.length; i++){
          System.out.println( players[i].getPlayerName() + "'s hand is currently" );
          players[i].seeHand();
        }
   }

   private static void makePlayerOutputs(){
       for ( int i = 0; i < players.length; i++){
           Logger.createPlayerOutputs( players[i].getPlayerName());
        }
   }

   private static void logInitialHand( Player player ){
       Logger.addToOutput( player.getPlayerName(), ( player.getPlayerName() + "'s initial hand is " ) );
       Logger.addToOutput( player.getPlayerName(), player.getHand() );
   }

   private static void isWinner( Player player ){
        boolean winner = true;
        int first = player.hand[0].getCardValue();

        for (Card element : player.hand) {
           if (element.getCardValue() != first) {
               winner = false;
            }
        }

        if ( winner == true ){
            Logger.addToOutput( player.getPlayerName(), ( player.getPlayerName() + " has won the game with a hand of " ) );
            Logger.addToOutput( player.getPlayerName(), player.getHand() );
            System.out.println( player.getPlayerName() + " has won the game with a hand of " );
            player.seeHand();
            System.exit(0);
        }
   }
}

Player类 public class Player实现Runnable     {         卡[]手;         String playerName;         int strategyChosen;         int playerNumber;

    private boolean running = true;
    private boolean paused = false;

    public void setPaused( boolean paused ){
        this.paused = paused;
    }

    public void run(){
        while(running){
            if(!paused){
              synchronized(this){  
                  playGame();
                }
         }
       }
    }

    private void playGame(){
        synchronized(this){
        switch(strategyChosen){
             case 1 : playStratOne();
             break;
             case 2 : playStratTwo();
             break;
            }
        }
    }

    public static void startPauseThread(){
     Thread add = new Thread( pauseInputThread );
     add.start();
   }


   static Thread pauseInputThread = new Thread(){
     private boolean running = true;
     private boolean paused = false;

      public void run(){ 
            while(running){
              if(!paused){
                  for(;;){
                    System.out.println("FEED ME");
                    Scanner reader = new Scanner(System.in);
                    String result = Checks.userInputCheck( "[pPrR]$" );
                       if( result == "p" ){
                           for ( int i = 0; i < CardGame.players.length; i++ ){
                            CardGame.players[i].setPaused( true );
                        }
                    }
                }
              }
            }
       }
      };

    private Player(){
    }

    private int getPlayerNumber(){
        return playerNumber;
    }

    public Player( int strategy, int cardsInHand, int playerNumber ){
        hand = new Card[cardsInHand];
        strategyChosen = strategy;
        this.playerNumber = playerNumber;
        playerName = "Player " + playerNumber;
    }

    public String getPlayerName(){
        return playerName;
    }

    public void fillHand(){
       for ( int i = 0; i < hand.length; i++){
            hand[i] = new Card(0);
       }
    }

    public void setHand( int value, int index ){
        hand[index].setCardValue( value );
    }

    public void seeHand(){
        for ( int i = 0; i < hand.length; i++){
            System.out.println( hand[i].getCardValue() );
        }
    }

    public String getHand(){
        String result = "";
        for ( int i = 0; i < hand.length; i++ ){
            result = result +  hand[i].getCardValue() + " \n" ;
        } 
        return result;
    }

    public int getHandValue( Card card ){
        return card.getCardValue();
    }

    private void playStratOne(){
        System.out.println("fuck");
    }

    private void playStratTwo(){
        synchronized(this){
            int index = 0;
            System.out.println( getPlayerName() + " discards a " + hand[index].getCardValue() + " to deck " + playerNumber );
            CardGame.playingDeckArray[playerNumber-1].add( new Card( getHandValue(hand[index])));

            for( int i = 1; i < hand.length+1; i++){
                if ( index == hand.length-1 ){
                    hand[index] = null;
                }else{
                    hand[index] = hand[index+i];
                    index = index + i; 
                }
            }
            if ( playerNumber == 1){
                System.out.println( getPlayerName() + " draws a " + ((CardGame.playingDeckArray[playerNumber + CardGame.playersNum - 2].poll()).getCardValue()) + " from deck " + ( CardGame.playersNum ) );
                hand[index] = CardGame.playingDeckArray[playerNumber + CardGame.playersNum - 2].poll();
            }else{
                System.out.println( getPlayerName() + " draws a " + (( CardGame.playingDeckArray[playerNumber - 2].poll()).getCardValue())  + " from deck " + ( playerNumber - 1 ) );
                hand[index] = CardGame.playingDeckArray[playerNumber - 2].poll();
            }

            System.out.println(getPlayerName()+ "'s hand is ");
            seeHand();
            for( int i = 0; i < CardGame.playingDeckArray.length; i++ ){
            }

            checkWinner();
        }
    }

    private void checkWinner(){
        boolean winner = true;
        int first = hand[0].getCardValue();

        for (Card element : hand) {
            if (element.getCardValue() != first) {
                winner = false;
            }
        }

        if ( winner == true ){
            Logger.addToOutput( getPlayerName(), ( getPlayerName() + " has won the game with a hand of " ) );
            Logger.addToOutput( getPlayerName(), getHand() );
            System.out.println( getPlayerName() + " has won the game with a hand of " );
            seeHand();
            System.exit(0);
        }
   }
}

卡类

 public class Card
 { 
    int cardValue;

    private Card(){
    }

    public Card( int value ){
        cardValue = value;
    }

    public void setCardValue( int value ){
        cardValue = value;
    }

    public int getCardValue(){
        return cardValue;
    }

    public  int getCardValue( Card card ){
        return cardValue;
    }
}

游戏的目的是拥有所有相同价值牌。

我想知道是否有办法让线程按顺序打印,而且我也不明白为什么会出现nullPointers和IndexOutOfBounds错误

这是手牌大小为2的2人游戏的结果

Hello, how many players would you like
2
Thank You


How many cards should each player begin with
2
Thank You


Which strategy would you like to use 1 or 2
2
Thank You

The deck has been created 
It is called deckfile.txt 

Please enter the name of the deck file
deckfile.txt
Thank You

Player 1's hand is currently
1
3
Player 2's hand is currently
2
3
Player 1 discards a 1 to deck 1
Player 1 draws a 4 from deck 2
Player 2 discards a 2 to deck 2
Player 1's hand is 
Player 2 draws a 4 from deck 1
3
2
Player 2's hand is 
3
1
Player 1 discards a 3 to deck 1
Player 2 discards a 3 to deck 2
Player 1 draws a 2 from deck 2
Player 2 draws a 1 from deck 1
Player 1's hand is 
2
3
Player 1 discards a 2 to deck 1
Player 2's hand is 
1
3
Player 2 discards a 1 to deck 2
Player 2 draws a 2 from deck 1
Player 2's hand is 
3

这给出了一个nullPointer异常,当我玩5手牌游戏的5人游戏时

Player 1's hand is currently
1
4
1
4
8
Player 2's hand is currently
2
1
1
3
1
Player 3's hand is currently
3
2
10
6
2
Player 4's hand is currently
3
7
5
8
6
Player 5's hand is currently
4
4
2
1
4
Player 1 discards a 1 to deck 1
Player 2 discards a 2 to deck 2
Player 5 discards a 4 to deck 5
Player 3 discards a 3 to deck 3
Player 4 discards a 3 to deck 4

我得到indexOutOfBounds异常

Exception in thread "Thread-8" Exception in thread "Thread-9" java.lang.ArrayIndexOutOfBoundsException: 6
at Player.playStratTwo(Player.java:132)
at Player.playGame(Player.java:38)
at Player.run(Player.java:27)
at java.lang.Thread.run(Thread.java:722)
如果我要求太多,请道歉,但是我们将不胜感激。

1 个答案:

答案 0 :(得分:1)

让我们看看以下代码:

int index = 0;
System.out.println( getPlayerName() + " discards a " + hand[index].getCardValue() + " to deck " + playerNumber );
CardGame.playingDeckArray[playerNumber-1].add( new Card( getHandValue(hand[index])));

for( int i = 1; i < hand.length+1; i++){
    if ( index == hand.length-1 ){
        hand[index] = null;
    }else{
        hand[index] = hand[index+i];
        index = index + i; 
    }
}

因此,在for循环开始时,index的值不能大于0。

如果hand.length是5,比如说,那么循环将从1变为5 - 运行起来很困惑,而“我不到一个数组的长度”,但这就是你的'得到了。一个潜在的问题是java数组从0开始,所以如果你的数组长度为5,那么它有0-4而不是1-5。如果您将数组声明为长度为6,则可能没问题。我没有挖掘你所有的代码来确定你是如何声明的。

所以循环从1到5;如果索引是4,则将该元素设置为null。因此,索引1,2,3和5处的值将尝试执行if语句的其他部分。如果它是5,那么你最好有一个数组,它将容纳索引6(长度为7),因为你有一个索引+ i进入数组。显然你没有,因为你的错误消息说6是一个超出范围的数组索引。

Java错误消息和堆栈跟踪是它最有用的两个特性。他们通常会告诉您问题是什么以及代码在何处被发现 - 这在编程领域并不普遍。如果您要使用Java编程,请学习相信您的错误消息,并学会阅读它们并从中获取信息作为解决问题的起点。

另外,我要说'索引'的使用令人困惑 - 除了我假设长度为+ 1且长度为1的拼写错误之外,它似乎仍然在循环中落后于'i'。如果你使用i迭代数组元素,那么我不能用来比较某些东西,看看你在哪里,下一步做什么等等,而不是使用另一个int?

最后,让我提醒您将数组的最后一个元素设置为null不会缩短数组。如果你有一个包含5个对象的数组并且你将最后一个设置为null,那么你在第5个元素中有一个null数组,而不是4个数组。我不知道你是否期望更改数组的长度,但你似乎有可能在这里给出了代码。