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