4

タスク-1日の指定された時間に電球のオンとオフを切り替えます。以下の情報に従って、コードを修正する方法を知る必要があります。また、タイマークラスを正しく使用しているかどうか、つまり、コードの設計が正しいかどうかを知る必要があります。コードは機能するかもしれませんが、後で問題を引き起こす可能性のある悪いデザインである可能性があります。私はそれが起こらないようにしたい。

出力は(これは私が本当に望んでいた出力ではありません:()-

This is the main program
Current time is - xxx
Future time is - xxx+5sec
Future time is - xxx+10sec
Main program ends
Bulb B1 is OFF

必要な出力-

This is the main program
Current time is - xxx
Future time is - xxx+5sec
Future time is - xxx+10sec
Bulb B1 is ON  //first on
Bulb B1 is OFF //then off
Main program ends//This should always be in the end.

以下のコードを修正して、必要なものを取得するにはどうすればよいですか?

Bulbクラス

class Bulb {

private boolean state = false;//On or off
private String name;

Bulb(String name){

    this.name = name;

}

public void setState(boolean state){

    this.state = state;
    if(this.state == true){

        System.out.println("Bulb " + name + " is ON");

    }else{

        System.out.println("Bulb " + name + " is OFF");

    }

}


public boolean getState(){
    return this.state;

}


}

BulbJobであるクラスTimerTask

import java.util.*;

class BulbJob extends TimerTask{

private Bulb bulbToHandle;
private boolean setBulbStateEqualTo;

BulbJob(Bulb toHandle){

    this.bulbToHandle = toHandle;

}


//NOTE: Must be called before run(), otherwise default value is used
public void setBulbStateEqualTo(boolean setBulbStateEqualTo){

    this.setBulbStateEqualTo = setBulbStateEqualTo;

}


//NOTE: call run() only before calling above method
public void run(){

    this.bulbToHandle.setState(setBulbStateEqualTo);//Set on or off

}

}

BulbSchedulerクラス-これは、電球がオンまたはオフになるタイミングをスケジュールします。

import java.util.*;

@SuppressWarnings( "deprecation" )
class BulbScheduler {

public static void main(String args[]) throws InterruptedException{

    System.out.println("This is the main program");

    Timer time = new Timer();
    Bulb b1 = new Bulb("B1");
    BulbJob bj = new BulbJob(b1);

    bj.setBulbStateEqualTo(true);//Task - Turn bulb on at time = afterCurrent

    Date current = new Date();//Get current time and execute job ten seconds after this time
    Date afterCurrent = (Date) current.clone();

    System.out.println("Current time is - " + current);

    int currentSecs = current.getSeconds();
    int offset = 5;//number of seconds

    afterCurrent.setSeconds(currentSecs + offset);
    System.out.println("Future time is - " + afterCurrent);

    time.schedule(bj, afterCurrent);//Schedule job "bj" at time = afterCurrent

    //Now turn the bulb off at new time = newest afterTime
    afterCurrent.setSeconds(currentSecs + 2 * offset);
    System.out.println("Future time is - " + afterCurrent);

    bj.setBulbStateEqualTo(false);//Task - Now turn the bulb off at time = afterCurrent

    System.out.println("Main program ends");

}

}
4

4 に答える 4

2

このセクション:

time.schedule(bj, afterCurrent);//Schedule job "bj" at time = afterCurrent

//Now turn the bulb off at new time = newest afterTime
afterCurrent.setSeconds(currentSecs + 2 * offset);

1つのタスクのみをスケジュールします。2回スケジュールする必要がある場合は、明示的にスケジュールしてください。

time.schedule(bj, afterCurrent);//Schedule job "bj" at time = afterCurrent

//Now turn the bulb off at new time = newest afterTime
afterCurrent.setSeconds(currentSecs + 2 * offset);
time.schedule(bj, afterCurrent);//Schedule job "bj" at time = afterCurrent

また。この行:

bj.setBulbStateEqualTo(false);

メインスレッドで実行されるため、両方のタスクの前に実行されます。そのステートメントを2つのタスク間で実行するようにスケジュールする必要があります。

于 2013-03-11T08:20:12.193 に答える
0

タイマーオブジェクトのschedule(TimerTask task、long delay)を使用することもできます。指定された遅延(ミリ秒)後に、指定されたタスクの実行をスケジュールします。変更されたコード-

import java.util.*;

class BulbScheduler {

    private static java.text.SimpleDateFormat sdf1 = new java.text.SimpleDateFormat ("yy MM dd HH mm ss");

//helper    
static String formatDate(Date d){
        return sdf1.format(d);
    }

    public static void main(String args[]) throws InterruptedException{
        System.out.println("This is the main method");
        java.util.GregorianCalendar cal = new java.util.GregorianCalendar();

        Bulb b1 = new Bulb("bulb 1", false);
        Bulb b2 = new Bulb("bulb 2", false);

        System.out.println("Time now " + formatDate(cal.getTime()));

        Timer timer = new Timer("bulbs");
        BulbJob b1On = new BulbJob(b1, true);
        BulbJob b1Off = new BulbJob(b1, false);
        BulbJob b2On = new BulbJob(b2, true);
        BulbJob b2Off = new BulbJob(b2, false);
        timer.schedule(b1On, 3 * 1000);//after 3 seconds
        timer.schedule(b2On, 7 * 1000);//after 4 seconds
        timer.schedule(b1Off, 6 * 1000);//after 6 seconds; before b2 on

        b1On = new BulbJob(b1, true);
        timer.schedule(b1On, 9 * 1000);


        //if you want main to wait need to add code here to make it wait,
        // but even if does the JVM wont exit. Its just a method. The JVM exits when all non daemon threads are done
        // or System.exit is called

        System.out.println("This is the main method ending; but other threads might be running ...");
        //main thread JVM waits for all other non dameons to end

    }

}

変更されたBulbJob

importjava.util。*;

クラスBulbJobはTimerTaskを拡張します{

private Bulb bulbToHandle;
private boolean bulbNewState;//dont start propert names with set

//why a seperate property when we need to set the new state everytime and cannot reuse jobs?
BulbJob(Bulb toHandle, boolean newState){
    this.bulbToHandle = toHandle;
    bulbNewState= newState;
}

public void run(){
    this.bulbToHandle.setState(bulbNewState);//Set on or off
}

}

class Bulb ... public void setState(boolean state){this.state = state; System.out.println( "Bulb" + name + "is" +(state? "on": "off")+ "at" + BulbScheduler.formatDate(new java.util.Date())); // if大丈夫

}

于 2013-03-11T10:25:26.293 に答える
0

コードは修正されていますが、このバージョンは最終的にmainを終了できません-

import java.util.*;

@SuppressWarnings( "deprecation" )
class BulbScheduler {

public static void main(String args[]) throws InterruptedException{

    System.out.println("This is the main program");

    Timer timeOn = new Timer();
    Timer timeOff = new Timer();
    Bulb b1 = new Bulb("B1");
    BulbJob bjOn = new BulbJob(b1);
    BulbJob bjOff = new BulbJob(b1);

    bjOn.setBulbStateEqualTo(true);//Task - Turn bulb on 
    bjOff.setBulbStateEqualTo(false);//Task - Then turn the bulb off later

    Date current = new Date();//Get current time and execute job ten seconds after this time
    Date afterCurrent = (Date) current.clone();

    System.out.println("Current time is - " + current);

    int currentSecs = current.getSeconds();
    int offset = 3;//number of seconds

    afterCurrent.setSeconds(currentSecs + offset);
    System.out.println("Future time is - " + afterCurrent);

    timeOn.schedule(bjOn, afterCurrent);//Schedule job "bj" at time = afterCurrent

    //Now turn the bulb off at new time = latest afterCurrent
    afterCurrent.setSeconds(currentSecs + 2 * offset);
    System.out.println("Future time is - " + afterCurrent);

    timeOff.schedule(bjOff, afterCurrent);

    System.out.println("Main program ends");

}

}
于 2013-03-11T09:02:01.027 に答える
0

時刻を正しく設定していません。GreogarianCalendarを使用する必要があります。

java.util.Dateは使用されますが、そのsetSecondsは使用できません。Javadocを読むと、かなり役に立ち、大いに役立ちます。public void setSeconds(int seconds)

非推奨。JDKバージョン1.1以降、Calendar.set(Calendar.SECOND、int seconds)に置き換えられました。この日付の秒を指定された値に設定します。このDateオブジェクトは、ローカルタイムゾーンで解釈されるように、年、月、日付、時、分が以前と同じで、指定された1秒以内の時点を表すように変更されます。

java.util.GregorianCalendarを使用する必要があります#add(Calendar.SECOND、howManySeconds)

次に、getDate()を使用してDateオブジェクトを取得し、Timerに送信します。

日付にsetSecondを呼び出しても、他のフィールドは変更されません。Calendar.addおよびrollのjavadocを参照してください。http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.htmlにアクセスして、クラスinroのルールを確認してください。

于 2013-03-11T09:15:32.363 に答える