Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.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 控制线程流_Java_Multithreading_Wait_Multitasking - Fatal编程技术网

Java 控制线程流

Java 控制线程流,java,multithreading,wait,multitasking,Java,Multithreading,Wait,Multitasking,我的任务是编写一个简单的游戏,模拟两个玩家一个接一个地进行1-3场比赛,直到一堆比赛结束。我设法让计算机选择随机值的比赛,但现在我想更进一步,让人类玩这个游戏。以下是我已经拥有的: 职业玩家是电脑玩家,玩家应该是人。问题是,PlayerMan的线程应该等到适当的匹配值被给出,但我不能让它以这种方式工作。逻辑如下:线程运行直到匹配项等于零。如果调用函数pickMatches()时播放器编号正确。在减少表上的匹配数后,线程应该等待,并通知另一个线程。我知道我必须使用wait()和notify(),但

我的任务是编写一个简单的游戏,模拟两个玩家一个接一个地进行1-3场比赛,直到一堆比赛结束。我设法让计算机选择随机值的比赛,但现在我想更进一步,让人类玩这个游戏。以下是我已经拥有的:

职业玩家是电脑玩家,玩家应该是人。问题是,PlayerMan的线程应该等到适当的匹配值被给出,但我不能让它以这种方式工作。逻辑如下:线程运行直到匹配项等于零。如果调用函数pickMatches()时播放器编号正确。在减少表上的匹配数后,线程应该等待,并通知另一个线程。我知道我必须使用wait()和notify(),但我无法正确放置它们。 共享类保留当前玩家的值以及匹配的数量

public void suspendThread() {
    suspended = true;
}

public void resumeThread() {
    suspended = false;
}

@Override
public void run(){
    int matches=1;
    int which = 0;
    int tmp=0;
    Shared data = this.selectData();
    String name = this.returnName();
    int number = this.getNumber();

    while(data.getMatches() != 0){

        while(!suspended){

            try{             
                which = data.getCurrent();

                if(number == which){

                    matches = pickMatches();

                    tmp = data.getMatches() - matches;
                    data.setMatches(tmp, number);

                    if(data.getMatches() == 0){
                        System.out.println("                          "+
                            name+" takes "+matches+" matches.");
                        System.out.println("Winner is player: "+name);
                        stop();
                    }

                    System.out.println("                          "+
                            name+" takes "+matches+" matches.");

                    if(number != 0){
                        data.setCurrent(0);
                    }
                    else{
                        data.setCurrent(1);
                    }
                }
                this.suspendThread();
                notifyAll();
                wait();

            }catch(InterruptedException exc) {}    
        }
    }
}

@Override
synchronized public int pickMatches(){
    Scanner scanner = new Scanner(System.in);
    int n = 0;
    Shared data = this.selectData();

    System.out.println("Choose amount of matches (from 1 to 3): ");

        if(data.getMatches() == 1){
            System.out.println("There's only 1 match left !");
            while(n != 1){
                n = scanner.nextInt();
            }
        }
        else{
            do{
                n = scanner.nextInt();
            }
            while(n <= 1 && n >= 3);
        }
    return n;
}
public void suspendThread(){
暂停=正确;
}
公共线程(){
暂停=错误;
}
@凌驾
公开募捐{
int匹配=1;
int=0;
int-tmp=0;
共享数据=此。选择数据();
字符串名称=this.returnName();
int number=this.getNumber();
while(data.getMatches()!=0){
当(!暂停){
试试{
其中=data.getCurrent();
如果(数字==哪个){
matches=pickMatches();
tmp=data.getMatches()-matches;
数据集匹配(tmp,编号);
if(data.getMatches()==0){
System.out.println(“”)+
name+“接受”+匹配项+“匹配项”。);
System.out.println(“获胜者是玩家:+name”);
停止();
}
System.out.println(“”)+
name+“接受”+匹配项+“匹配项”。);
如果(数字!=0){
数据。设置电流(0);
}
否则{
数据。设定电流(1);
}
}
这个.suspendThread();
notifyAll();
等待();
}catch(InterruptedException exc){}
}
}
}
@凌驾
同步的公共int-pickMatches(){
扫描仪=新的扫描仪(System.in);
int n=0;
共享数据=此。选择数据();
System.out.println(“选择匹配数量(从1到3):”;
if(data.getMatches()==1){
System.out.println(“只剩下1个匹配项了!”);
而(n!=1){
n=scanner.nextInt();
}
}
否则{
做{
n=scanner.nextInt();
}
而(n=3);
}
返回n;
}

}

首先,我要说的是,我认为你让这件事变得比你需要的更艰难了。如果是我,我会创建一个“GameMaster”类,其任务是循环并告诉每个玩家轮到他们的时候。你的玩家类没有循环,只有一个takeTurn方法。通过这种方式,您可以从播放器类中删除等待/通知行为


如果您希望保留现有的设计,我仍然会放弃等待/通知,并使用一个。检查文档的正确用法,但要点是删除suspend/resume方法,在循环的顶部调用acquire(),在循环的底部调用release。只需确保在构造函数中将fairity设置为true,这样您就不必担心玩家通过连续两次获取信号量锁来连续两次轮换。

好的,所以我在不等待()的情况下成功地做到了这一点


当您发现自己必须在线程之间设置通信以同步它们的执行时,只是为了发生指定的事件序列(例如轮流玩游戏),这是一个好迹象,表明您可能拥有的线程比您需要的多


在这种情况下,考虑在一个播放器类的各种扩展上执行一个TaKururn()方法的单个线程可能会使您的生活更容易。您可以使Player成为一个要求.takeTurn()的抽象基类,然后让HumanPlayer和MachinePlayer类封装对该方法中的每种类型的播放器都有意义的代码。与大量的wait()和notify()相比,这将使对更多玩家的扩展变得相对简单。

@owca太多代码了!尝试使其更符合简短的自包含可编译示例(sscce):