Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用wait()和Notify()在4个线程之间执行线程间通信时获取IllegalMonitorStateException_Java_Multithreading - Fatal编程技术网

Java 使用wait()和Notify()在4个线程之间执行线程间通信时获取IllegalMonitorStateException

Java 使用wait()和Notify()在4个线程之间执行线程间通信时获取IllegalMonitorStateException,java,multithreading,Java,Multithreading,我只想在下一轮等于当前线程时运行线程,例如,如果nextTurn=3,则只有为播放器3创建的线程才应运行,其他线程应处于等待状态。和其他线程一样,下面的程序持续无限次地改变回合,所以我想要一个特定于回合的线程应该无限次地运行 import static java.util.Collections.shuffle; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.ut

我只想在下一轮等于当前线程时运行线程,例如,如果nextTurn=3,则只有为播放器3创建的线程才应运行,其他线程应处于等待状态。和其他线程一样,下面的程序持续无限次地改变回合,所以我想要一个特定于回合的线程应该无限次地运行

 import static java.util.Collections.shuffle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class DemoMain {

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        int sizeOfDeck = 31;
        System.out.println("Enter cards in the Deck");
        ArrayList<Integer> cardNumber = new ArrayList<Integer>(sizeOfDeck);
//      for (int i = 0; i <= sizeOfDeck; i++) {
//          Scanner input = new Scanner(System.in);
//          cardNumber.add(input.nextInt());
//      }
        for(int i=0 ; i<=31;i++)
        {
            cardNumber.add(i);
        }
        System.out.println("Cards: "+ cardNumber );

        shuffle(cardNumber);
        List<Integer> Piles1 = cardNumber.subList(0, 4);
        List<Integer> Piles2 = cardNumber.subList(4, 8);
        List<Integer> Piles3 = cardNumber.subList(8, 12);
        List<Integer> Piles4 = cardNumber.subList(12, 16);

        List<Integer> player1Card = cardNumber.subList(16, 20);
        List<Integer> player2Card = cardNumber.subList(20, 24);
        List<Integer> player3Card = cardNumber.subList(24, 28);
        List<Integer> player4Card = cardNumber.subList(28, 32);

        Map<Integer, Integer> player1Map = getPlayerCards(player1Card);
        Map<Integer, Integer> player2Map = getPlayerCards(player2Card);
        Map<Integer, Integer> player3Map = getPlayerCards(player3Card);
        Map<Integer, Integer> player4Map = getPlayerCards(player4Card);


        Player p1 = new Player(player1Map, Piles1, Piles2, "Player1");
        Player p2 = new Player(player2Map, Piles2, Piles3, "Player2");
        Player p3 = new Player(player3Map, Piles3, Piles4, "Player3");
        Player p4 = new Player(player4Map, Piles4, Piles1, "Player4");


        p1.start();

        p2.start();

        p3.start();

        p4.start();


    }

    private static Map<Integer, Integer> getPlayerCards(List<Integer> playerCard) {

        Map<Integer, Integer> cardsMap = null;

        for (Integer card : playerCard) {
            if (cardsMap == null) {
                cardsMap = new HashMap<Integer, Integer>();
            }

            Integer count = cardsMap.get(card);
            if (count == null) {
                cardsMap.put(card, 1);
            } else {
                cardsMap.put(card, cardsMap.get(card) + 1);
            }
        }

        return cardsMap;
     }
    }
导入静态java.util.Collections.shuffle;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Scanner;
公共类DemoMain{
公共静态void main(字符串[]args)引发InterruptedException{
//TODO自动生成的方法存根
int sizeOfDeck=31;
System.out.println(“在卡片组中输入卡片”);
ArrayList cardNumber=新的ArrayList(sizeOfDeck);
//对于(int i=0;i要在对象上使用
wait()/notify()
,线程必须拥有该对象上的监视器。
由于您创建了一个新的
StringBuffer
实例并将其分配给
Nextturn
,同时线程拥有监视器:

Nextturn = new StringBuffer("Player1");
我假设当前线程丢失了监视器,或者至少在新对象上没有监视器。因此,您不能再调用
Nextturn上的
wait()/notify()
例如:

nextTurn(); // you assign the variable to a new object
Nextturn.notifyAll(); // but you notify on that new object
或者,使用一个简单的对象表示回合的锁定,使用一个
字符串
表示当前玩家:

final Object lockOnTurn = new Object();
String currentPlayer = "...";
// ..
private void playNew() throws InterruptedException {
    synchronized (lockOnTurn) {
        while(true) {               
            if (! playerTrun.equalsIgnoreCase(String.valueOf(currentPlayer))) {
                try {
                    System.out.println("waiting: "+ playerTrun);
                    lockOnTurn.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("Running: "+playerTrun);
                currentPlayer = nextTurn();
                lockOnTurn.notifyAll();
            }
        }
    }
}

是的,我现在做更改,我没有得到任何错误,但它只运行一次,我想无限次地运行它
final Object lockOnTurn = new Object();
String currentPlayer = "...";
// ..
private void playNew() throws InterruptedException {
    synchronized (lockOnTurn) {
        while(true) {               
            if (! playerTrun.equalsIgnoreCase(String.valueOf(currentPlayer))) {
                try {
                    System.out.println("waiting: "+ playerTrun);
                    lockOnTurn.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("Running: "+playerTrun);
                currentPlayer = nextTurn();
                lockOnTurn.notifyAll();
            }
        }
    }
}