4 votes

Besoin de corriger mon code Java Timer

Tâche - Allumer et éteindre une ampoule à un moment précis de la journée. J'ai besoin de savoir comment fixer mon code selon les informations données ci-dessous. J'ai également besoin de savoir si j'utilise la classe timer correctement, c'est-à-dire si la conception de mon code est correcte. Le code peut fonctionner, mais il peut s'agir d'une mauvaise conception qui causera des problèmes plus tard. Je ne veux pas que cela se produise.

Le résultat est (Ce n'est pas le résultat que je voulais vraiment :( ) -

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

Résultat souhaité -

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.

Comment puis-je corriger le code ci-dessous pour obtenir ce que je veux ?

Bulb Classe

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 qui est une classe 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 class - cette fonction permet de programmer l'allumage ou l'extinction de l'ampoule.

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");

}

}

2voto

assylias Points 102015

Cette section :

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);

ne planifie qu'une seule tâche. Si vous devez la programmer deux fois, faites-le explicitement :

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

De même, cette ligne :

bj.setBulbStateEqualTo(false);

est exécuté dans le fil d'exécution principal, il précède donc l'exécution de ambos tâches. Vous devez planifier l'exécution de cette instruction entre les deux tâches.

0voto

Time Points 163

Le code est corrigé, mais cette version ne peut pas sortir de main à la fin -

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");

}

}

0voto

tgkprog Points 2115

Vous ne réglez pas l'heure correctement. Vous devez utiliser GreogarianCalendar.

java.util.Date est utilisé mais ne peut pas utiliser son setSeconds Lisez la Javadoc, elle est assez bonne et vous aidera beaucoup. public void setSeconds(int seconds)

Déclassé. A partir de la version 1.1 du JDK, remplacé par Calendar.set(Calendar.SECOND, int seconds). Fixe les secondes de cette Date à la valeur spécifiée. Cet objet Date est modifié de manière à représenter un point dans le temps dans la seconde spécifiée de la minute, avec l'année, le mois, la date, l'heure et la minute comme auparavant, tel qu'interprété dans le fuseau horaire local.

Vous devez utiliser java.util.GregorianCalendar # add(Calendar.SECOND, howManySeconds)

puis utiliser getDate() pour obtenir l'objet Date et l'envoyer à la minuterie.

L'appel à setSecond sur une date ne modifie pas les autres champs. Voir la doc java de Calendar.add et roll. http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html et voir les règles dans l'inro de la classe.

0voto

tgkprog Points 2115

Peut également utiliser la planification de l'objet timer(TimerTask task, long delay) Planifie l'exécution de la tâche spécifiée après le délai spécifié (millisecondes). Code modifié -

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

    }

}

Changé BulbJob

import java.util.* ;

class BulbJob extends 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
}

}

classe 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()));//si ok aussi

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X