.wait()和.notifyAll()无法正常工作

时间:2017-11-29 22:38:54

标签: java multithreading

我正在开发一个应该实例化n个线程的程序。他们的工作是从一张存在52张不同卡片的牌组中抽出,等到该轮被评估(谁拥有最高牌)并且用户显示最高牌,然后重复直到牌组为空。

第一轮运行完美,没有考虑卡的错误评估,但随后程序才锁定。永远不要画新卡。

我无法弄清问题是什么,但我的猜测是我在线程唤醒之前调用notifyAll(),导致死锁。即使我正在计算等待线程的数量,并且仅通知等待线程的数量是否与玩家的数量相对应。

编辑:我发现如果我调试,代码运行顺利并按预期运行。但是一旦我运行它,它就像前面描述的那样运行。

public class Deck {
Stack<Card> stack = new Stack<>();


public Deck()
{
   makeAndShuffleDeck();
}

public synchronized Card drawOneCard()
{
    Card card = stack.pop();
    System.out.println(Thread.currentThread() + " is drawing " + card);
    return card;
}

public void setCardValues(int x)
{
    if(x == 0)
    {
        Rank.ACE.setValue(14);
    }
    else
    {
        Rank.ACE.setValue(1);
    }
}

public void makeAndShuffleDeck()
{
    for(Suit suit : Suit.values())
    {
        for(Rank value : Rank.values())
        {
            stack.add(new Card(suit,value));
        }
    }
    Collections.shuffle(stack);
}

public Stack<Card> getDeck()
{
    return stack;
}

}

public class Round {
ArrayList<Thread> playersInTheRound = new ArrayList<>();
ArrayList<Card> cardsDrawnInTheRound = new ArrayList<>();
Deck deck;
int numberOfRounds;

public Round(int nrOfPlayers, Deck deck)
{
    this.deck = deck;
    fillListWithPlayers(nrOfPlayers);
    calcNumberOfRounds();
    for(Thread p: playersInTheRound)
    {
        p.start();
    }
}

public void fillListWithPlayers(int nrOfPlayers)
{
    for (int i = 0; i < nrOfPlayers; i++)
    {
        playersInTheRound.add(new Thread(new Player(deck, this)));
    }
}

public void addPlayerCards(Card card)
{
    cardsDrawnInTheRound.add(card);
}

public void calcNumberOfRounds()
{
    numberOfRounds = deck.getDeck().size()/playersInTheRound.size();
}

public void playRound()
{
    while(numberOfRounds > 0)
    {
        findWinnerOfRound();
        cardsDrawnInTheRound.clear();


        while(Player.waiting == playersInTheRound.size())
        {
            synchronized (this)
            {
                this.notifyAll();
            }
            Player.waiting = 0;
        }

        numberOfRounds--;
    }
}

public void findWinnerOfRound()
{
    Card highestCard = null;
    Comparator<Card> comp = (Card c1, Card c2) ->
    {
        if (c1.rank.getValue() == c2.rank.getValue())
        {
            if (c1.suit.getRank() > c2.suit.getRank())
            {
                return 1;
            }
            return -1;
        }
        if (c1.rank.getValue() > c2.rank.getValue())
        {
            return 1;
        }
        return -1;
    };

    for (int i = 0; i < cardsDrawnInTheRound.size()-1; i++)
    {
        for (int j = i+1; j <  cardsDrawnInTheRound.size(); j++)
        {
            if(comp.compare(cardsDrawnInTheRound.get(i), cardsDrawnInTheRound.get(j)) == -1)
            {
                highestCard = cardsDrawnInTheRound.get(j);
            }
            highestCard = cardsDrawnInTheRound.get(i);
        }
    }
    System.out.println(cardsDrawnInTheRound);
    System.out.println("Winner: " + highestCard);
}

}

public class Player implements Runnable {
Deck deck;
Round round;
public static int waiting = 0;

public Player(Deck deck, Round round)
{
    this.deck = deck;
    this.round = round;
}

@Override
public void run()
{
    Card card = deck.drawOneCard();
    synchronized (round)
    {
        try
        {
            round.addPlayerCards(card);
            waiting++;
            round.wait();
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

}

0 个答案:

没有答案