Drukuj „hello world” co X sekund

130

Ostatnio do drukowania używam pętli z dużymi liczbami Hello World:

int counter = 0;

while(true) {
    //loop for ~5 seconds
    for(int i = 0; i < 2147483647 ; i++) {
        //another loop because it's 2012 and PCs have gotten considerably faster :)
        for(int j = 0; j < 2147483647 ; j++){ ... }
    }
    System.out.println(counter + ". Hello World!");
    counter++;
}

Rozumiem, że jest to bardzo głupi sposób, aby to zrobić, ale nigdy jeszcze nie korzystałem z żadnych bibliotek timerów w Javie. Jak zmodyfikować powyższe, aby drukować co powiedzmy 3 sekundy?

meiryo
źródło
1
Chociaż poniższe odpowiedzi powinny oczywiście odpowiedzieć na twoje pytanie, powinieneś również zauważyć, że sposób, w jaki to robisz, spowodowałby inny interwał na każdym komputerze. Zależy od tego, jak szybko może uruchomić kompilator.
IHazABone
Możliwy duplikat
wywoływania

Odpowiedzi:

190

Możesz również przyjrzeć się klasom Timeri TimerTaskklasom, których możesz użyć, aby zaplanować uruchamianie zadania co nsekundę.

Potrzebujesz klasy, która rozszerza TimerTaski przesłania public void run()metodę, która będzie wykonywana za każdym razem, gdy przekażesz wystąpienie tej klasy dotimer.schedule() metody.

Oto przykład, który jest drukowany Hello Worldco 5 sekund: -

class SayHello extends TimerTask {
    public void run() {
       System.out.println("Hello World!"); 
    }
}

// And From your main() method or any other method
Timer timer = new Timer();
timer.schedule(new SayHello(), 0, 5000);
Rohit Jain
źródło
9
Zauważ, że schedulemetoda 2-param zostanie wykonana raz po określonym czasie. 3-param schedulelub scheduleAtFixedRatenależałoby użyć.
Tim Bender
4
@TimBender Zastanawiam się tylko, czy OP naprawdę wykonał swoje zadanie;) Tak czy inaczej, teraz wolałbym używać ExecutorServicedo tych zadań. To naprawdę duża poprawa w stosunku do tradycyjnego interfejsu API wątków. Po prostu nie użyłem go w momencie odpowiadania.
Rohit Jain
4
Timer timer = new Timer(true);powinien być ustawiony na truedemona. Chyba że chcesz, aby licznik czasu nadal działał po zamknięciu aplikacji.
Tomasz Mularczyk
Należy pamiętać, że w tym rozwiązaniu stosowane są „stałe opóźnienia po wykonaniu poprzedniego zadania”, co oznacza, że ​​opóźnienie rozpoczyna się po zakończeniu poprzedniego cyklu. Jeśli proces był opóźniony (np. Wyrzucanie elementów bezużytecznych), czas będzie wyłączony. Jeśli chcesz dokładności, na przykład w przypadku długo działających wątków, zsynchronizuj się z datą
keesp
po gwiazdce to w zaćmieniu, jak można zatrzymać ten zegar? Nawet ja go zamknąłem, prawda?
Vijay
203

Jeśli chcesz wykonać zadanie okresowe, użyj pliku ScheduledExecutorService. W szczególności ScheduledExecutorService.scheduleAtFixedRate

Kod:

Runnable helloRunnable = new Runnable() {
    public void run() {
        System.out.println("Hello world");
    }
};

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(helloRunnable, 0, 3, TimeUnit.SECONDS);
Tim Bender
źródło
10
Mam nadzieję, że ktoś inny też to poprze. Thread.sleep () może najlepiej pasować do kodu w OP, ale jest to raczej amatorskie odkrycie koła. Profesjonalni inżynierowie oprogramowania będą używać wypróbowanego i zaufanego interfejsu API, takiego jak TimerTask. Usługa ScheduledExecutorService jest jednak jeszcze lepsza; patrz Brian Goetz i wsp., Java Concurrency in Practice . Ta ostatnia klasa istnieje już od prawie dziesięciu lat - to smutne, że wszystkie inne odpowiedzi ją pomijają.
Michael Scheper
2
@MichaelScheper, Dziękuję, cieszę się, że ta odpowiedź w końcu przekroczyła ten TimerTaskwariant. Co ciekawe, zauważyłem, że przyjęta odpowiedź jest w rzeczywistości nieprawidłowa: \ Pomijając wiek obu API, ScheduledExecutorServicejest po prostu bardziej intuicyjnie deklaratywny. Użycie TimeUnitparametru jako parametru sprawia, że ​​jest dużo bardziej jasne, co się dzieje. Dawno minęły czasy, takie jak kod 5*60*1000 // 5 minutes.
Tim Bender,
2
@TimBender Zauważyłem, że masz 3 jako argument z kropką. Nie mogę znaleźć, czy to w sekundach, czy milisekundach. Chciałbym, aby był uruchamiany co 500 milisekund (pół sekundy).
JohnMerlino
2
Ahh rozumiem. Czwarty argument pozwala określić czas np. TimeUnit.MILLISECONDS.
JohnMerlino
1
@TerryCarter W Javie8 + Zamiast tego możesz zrobić Runnable helloRunnable = () -> { /*code */ };to, co jest jeszcze piękniejsze;)
Joel
16

Rozumiem to za pomocą timera, mam nadzieję, że to pomoże. Użyłem timera z java.util.Timeriz TimerTasktego samego pakietu. Zobacz poniżej:

TimerTask task = new TimerTask() {

    @Override
    public void run() {
        System.out.println("Hello World");
    }
};

Timer timer = new Timer();
timer.schedule(task, new Date(), 3000);
tmwanik
źródło
9

Możesz użyć Thread.sleep(3000)wewnątrz do pętli.

Uwaga: będzie to wymagało try/catchblokady.

saum22
źródło
6
public class HelloWorld extends TimerTask{

    public void run() {

        System.out.println("Hello World");
    }
}


public class PrintHelloWorld {
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new HelloWorld(), 0, 5000);

        while (true) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                System.out.println("InterruptedException Exception" + e.getMessage());
            }
        }
    }
}

Utworzono nieskończoną pętlę Zadanie harmonogramu reklam zostało skonfigurowane.

Vicky
źródło
4

Najprostszym sposobem byłoby uśpienie głównego wątku na 3000 milisekund (3 sekundy):

for(int i = 0; i< 10; i++) {
    try {
        //sending the actual Thread of execution to sleep X milliseconds
        Thread.sleep(3000);
    } catch(InterruptedException ie) {}
    System.out.println("Hello world!"):
}

Spowoduje to zatrzymanie wątku na co najmniej X milisekund. Wątek może spać dłużej, ale to zależy od JVM. Jedyną gwarantowaną rzeczą jest to, że wątek będzie spał co najmniej przez te milisekundy. Spójrz na Thread#sleepdokument:

Powoduje uśpienie aktualnie wykonywanego wątku (tymczasowe wstrzymanie wykonywania) na określoną liczbę milisekund, w zależności od precyzji i dokładności systemowych timerów i harmonogramów .

Luiggi Mendoza
źródło
Dzięki @Luiggi. Java zawsze zapewni 3000 ms bez względu na to, na jakiej maszynie (CPU) ją uruchomię, prawda?
meiryo
@NandkumarTekale chcesz rozwinąć więcej?
meiryo
4
@meiryo Zatrzyma wątek na co najmniej X milisekund. Wątek może spać dłużej, ale to zależy od JVM. Jedyną gwarantowaną rzeczą jest to, że wątek będzie spał co najmniej przez te milisekundy.
Luiggi Mendoza,
4
Uwaga: jeśli nie jest to system czasu rzeczywistego, sen będzie trwał co najmniej 3000 ms, ale może być dłuższy. Jeśli chcesz mieć dokładnie 3000 ms snu, szczególnie tam, gdzie zagrożone jest życie ludzkie (instrumenty medyczne, samoloty sterujące itp.), Powinieneś użyć systemu operacyjnego czasu rzeczywistego.
Kinjal Dixit
@LuiggiMendoza Czy istnieje rozwiązanie, w którym wykonanie nie jest wstrzymane? Hello world to tylko przykład. Właściwie chcę wysyłać prosty pakiet DatagramPacket z klienta UDP na jego serwer co 3 sekundy. Byłoby Thread.sleepodpowiednie?
meiryo
3

Zastosowanie java.util.Timeri Timer#schedule(TimerTask,delay,period)metoda pomoże ci.

public class RemindTask extends TimerTask {
    public void run() {
      System.out.println(" Hello World!");
    }
    public static void main(String[] args){
       Timer timer = new Timer();
       timer.schedule(new RemindTask(), 3000,3000);
    }
  }
Subhrajyoti Majumder
źródło
2

Oto prosty sposób korzystania z wątku w java:

for(int i = 0; i< 10; i++) {
    try {
        //sending the actual Thread of execution to sleep X milliseconds
        Thread.sleep(3000);
    } catch(Exception e) {
        System.out.println("Exception : "+e.getMessage());
    }
    System.out.println("Hello world!");
}
user3928455
źródło
1

Co on powiedział. Możesz obsłużyć wyjątki w dowolny sposób, ale Thread.sleep (miliseconds); to najlepsza trasa.

public static void main(String[] args) throws InterruptedException {
leigero
źródło
1

Oto kolejny prosty sposób użycia interfejsu Runnable w konstruktorze wątków

public class Demo {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                for(int i = 0; i < 5; i++){
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("Thread T1 : "+i);
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                for(int i = 0; i < 5; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("Thread T2 : "+i);
                }
            }
        });

        Thread t3 = new Thread(new Runnable() {

            @Override
            public void run() {
                for(int i = 0; i < 5; i++){
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("Thread T3 : "+i);
                }
            }
        });

        t1.start();
        t2.start();
        t3.start();
    }
}
Mayur Chudasama
źródło
0

Dodaj Thread.sleep

try {
        Thread.sleep(3000);
    } catch(InterruptedException ie) {}
Russell Gutierrez
źródło
0

W przypadku małych aplikacji dobrze jest używać Timer i TimerTask, jak wspomniał Rohit, ale w aplikacjach internetowych użyłbym Quartz Scheduler do planowania zadań i wykonywania takich okresowych zadań.

Zobacz samouczki dotyczące planowania Quartz.

Nandkumar Tekale
źródło
-1
public class TimeDelay{
  public static void main(String args[]) {
    try {
      while (true) {
        System.out.println(new String("Hello world"));
        Thread.sleep(3 * 1000); // every 3 seconds
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
user3017805
źródło