我有一个Rotor对象,它的目标速度和当前速度都为目标。每个人都试图更改其currentSpeed以匹配所设定的GoalSpeed。我有4个这样的转子运行4个独立的线程。控制器会定期为每个人分配一个新的GoalSpeed。

当我尝试在每个转子中更改其currentSpeed时,我永远不能超过所有转子的currentSpeed之和来超过X值。 sum(currentSpeed(Rotor1)+ ... + currentSpeed(Rotor2))!> X.

这是我的问题:检查是否可以增加转子的当前速度时,我会在速度总和条件下执行if语句。但是,由于每个转子都是单独的螺纹,另一个转子会改变其值,因此可能在检查之后立即进行。因此,我在另一个线程中的签入不再有效。如何确保当我处于一个转子的setNewSpeed()方法中时,没有其他转子会改变其当前速度?

class Rotor implements Runnable {
    private int id;
    private int goalSpeed;
    private int currentSpeed;
    private Controller controller;
    private int Y;
    private int failedAttempts;
    private int successAttempts;
    private int maxSpeed;

    public int getSuccessAttempts() {
        return successAttempts;
    }

    public void setSuccessAttempts(int successAttempts) {
        this.successAttempts = successAttempts;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public void setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    public int getFailedAttempts() {
        return failedAttempts;
    }

    public Rotor(Controller c, int Y, int id){
        this.controller = c;
        this.Y = Y;
        this.id = id;
        this.currentSpeed = 0;
        this.failedAttempts = 0;
        this.goalSpeed = 0;
        this.maxSpeed = 0;
        this.successAttempts = 0;
    }

    synchronized public void setGoalSpeed(int s){
        this.goalSpeed = s;
    }

    public int getCurrentSpeed(){
        return currentSpeed;
    }

    synchronized private void setNewSpeed(){
        int currentDrain = 0;
        for(Rotor r : controller.getRotors()){
            currentDrain = currentDrain + r.getCurrentSpeed();
        }
        if((currentDrain + (goalSpeed - currentSpeed)) > 20){
            //we cannot increase by total amount because drain too high
            System.out.println("failed");
            this.failedAttempts++;
            currentSpeed = currentSpeed + (20 - currentDrain);
            System.out.println("currentSpeed:" + currentSpeed);
        } else {
            System.out.println("success");
            successAttempts++;
            currentSpeed = goalSpeed;
        }
//      System.out.println("goalSpeed:" + goalSpeed);
//      System.out.println("currentDrain:" + currentDrain);

}

    public void run() {
        try {
            while(true){
                setNewSpeed();
                if(currentSpeed > maxSpeed){
                    maxSpeed = currentSpeed;
                }

                Thread.sleep(Y);
            }
        } catch (InterruptedException e) {
            System.out.println("Rotor " + id + ": checks=" + (int)(successAttempts + failedAttempts) + ", success rate=" + successAttempts + ", failedAttempts=" + failedAttempts + ", max=" + maxSpeed);
        }
    }
}

最佳答案

同步所有转子之间共享的锁。现在他们每个人都在自己的锁(即this)上进行同步,因此即使该方法已同步,也可以同时在不同的对象上调用该方法。

10-06 07:25