首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用java编写的竞赛代码不起作用

用java编写的竞赛代码不起作用
EN

Stack Overflow用户
提问于 2014-11-14 13:21:34
回答 2查看 1.2K关注 0票数 0

我对Java很陌生,我编写了这个种族程序。我试图运行它,但是它在种族和RaceMain类中给出了一个非法的Monitor状态异常错误.你能帮忙吗?

代码语言:javascript
复制
public class RaceMain {
    public static void main(String args[]) throws InterruptedException{     
        Pitstop p = new Pitstop();
        Race r = new Race();
        new Car("Ryan Hunter", r, p);
        new Car("Takumo Sato", r, p);
        new Car("Scott Dixon", r, p);
        new Car("Sebastien Bourdais", r, p);
        r.StartRace();
    }
}

public class Race {
int rank = 0;

    void getToStart() throws InterruptedException{
        wait();
    }

    void StartRace() throws InterruptedException{
        Thread.sleep(1000);
        notifyAll();
    }

    synchronized void FinishRace(Car c){
        rank = rank +1;
        System.out.println("<<<<<<" + c.name + " finished " + geth(rank) + ">>>>>>");
    }

    String geth(int i){
        switch(i % 10){
        case 1:
            return i + "st";
        case 2:
            return i + "nd";
        case 3: 
            return i +"rd";
        default:
            return i + "th";
        }
    }
}

public class Car implements Runnable{
String name;
Race r;
Pitstop p;
int rand;
int lapsCompleted;
boolean needRep = false;

Car(String n, Race r, Pitstop p){
    name = n;
    this.r = r;
    this.p = p;
}

public void run(){
    try{
        r.getToStart();
        System.out.println(name + " is off and speeding!");
        for(int i = 1; i < 10; i++){
            if(needRep){
                p.repair(name);
                needRep = false;
            }
            runLap();
        }
    }catch(InterruptedException e){
        System.out.println(e);
    }
}

void runLap() throws InterruptedException{
    rand = (int)(Math.random() % 500) + 1000;
    Thread.sleep(rand);
    System.out.println(name + " completed his " + geth(lapsCompleted) + " lap");
    if(Math.floor(Math.random()*10) == 5){
        System.out.println("Oh snap! Looks like " + name + "'s tire has got bursted during the race!");
        needRep = true;
    }
}   

String geth(int i){
    switch(i % 10){
        case 1:
            return i + "st";
        case 2:
            return i + "nd";
        case 3: 
            return i +"rd";
        default:
            return i + "th";
        }
    }
}


public class Pitstop {
    synchronized void repair(String n) throws InterruptedException{
        int dur = (int) (Math.random() * 1000) % 1000 + 5000;
        Thread.sleep(dur);
        double sec = dur / 1000;
        System.out.println(n + " stopped for " + sec);
   }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-14 14:22:15

似乎您希望运行多个线程,因为Car实现了Runnable

这将是正确的做法:

代码语言:javascript
复制
    Pitstop p = new Pitstop();
    Race r = new Race();
    new Thread(new Car("Ryan Hunter", r, p)).start();
    new Thread(new Car("Takumo Sato", r, p)).start();
    new Thread(new Car("Scott Dixon", r, p)).start();
    new Thread(new Car("Sebastien Bourdais", r, p)).start();
    r.StartRace();

现在,就这两种方法而言,我将完全删除它们。首先是因为它们被错误地从错误的线程中调用,其次是因为我没有看到它们的目的:

代码语言:javascript
复制
void getToStart() throws InterruptedException{
    // remove this
}

void StartRace() throws InterruptedException{
    // remove this
}

现在可以在run方法中添加一个Thread.yield,如下所示:

代码语言:javascript
复制
    public void run() {
        try {
            System.out.println(name + " is off and speeding!");
            for (int i = 1; i < 10; i++) {
                if (needRep) {
                    p.repair(name);
                    needRep = false;
                }
                runLap();
                Thread.yield();
            }
        } catch (InterruptedException e) {
            System.out.println(e);
        }

结果:

代码语言:javascript
复制
    Takumo Sato is off and speeding!
    Sebastien Bourdais is off and speeding!
    Ryan Hunter is off and speeding!
    Scott Dixon is off and speeding!
    Ryan Hunter completed his 1st lap
    Scott Dixon completed his 1st lap
    Sebastien Bourdais completed his 1st lap
    Takumo Sato completed his 1st lap
    Oh snap! Looks like Ryan Hunter's tire has got bursted during the race!
    Scott Dixon completed his 2nd lap
    Sebastien Bourdais completed his 2nd lap
    Takumo Sato completed his 2nd lap
    Scott Dixon completed his 3rd lap
    Oh snap! Looks like Scott Dixon's tire has got bursted during the race!
    Sebastien Bourdais completed his 3rd lap
    Takumo Sato completed his 3rd lap
    Oh snap! Looks like Takumo Sato's tire has got bursted during the race!
票数 0
EN

Stack Overflow用户

发布于 2014-11-14 14:10:39

您有两个需要同步的竞赛代码的方法:

getToStart()抛出InterruptedException{ wait();} StartRace()抛出InterruptedException{ Thread.sleep(1000);notifyAll();}

这两个方法都调用只有在同步块中有效的其他方法:

  • Object.wait():如果当前线程不是对象监视器的所有者,则抛出IllegalMonitorStateException。
  • 如果当前线程不是此对象的监视器的所有者,Object.notifyAll()将抛出IllegalMonitorStateException。

您的方法需要同步:

代码语言:javascript
复制
synchronized void getToStart() throws InterruptedException{
    wait();
}

synchronized void StartRace() throws InterruptedException{
    Thread.sleep(1000);
    notifyAll();
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26931780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档