我正在开发一个应该实例化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();
}
}
}
}