In thế giới xin chào thế giới, mỗi X giây


127

Gần đây tôi đã sử dụng các vòng lặp với số lượng lớn để in ra 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++;
}

Tôi hiểu rằng đây là một cách rất ngớ ngẩn để làm điều đó, nhưng tôi chưa bao giờ sử dụng bất kỳ thư viện hẹn giờ nào trong Java. Làm thế nào một người sửa đổi ở trên để in cứ sau 3 giây?


1
Mặc dù các câu trả lời dưới đây rõ ràng sẽ trả lời câu hỏi của bạn, bạn cũng nên lưu ý rằng cách bạn thực hiện sẽ dẫn đến một khoảng khác nhau trên mỗi máy. Phụ thuộc vào tốc độ nó có thể chạy trình biên dịch.
IHazABone

Bản sao có thể có của Gọi một chức năng cứ sau 10 phút
Alex.K.

Câu trả lời:


187

Bạn cũng có thể xem TimerTimerTaskcác lớp mà bạn có thể sử dụng để lên lịch cho nhiệm vụ của mình để chạy mỗi ngiây.

Bạn cần một lớp mở rộng TimerTaskvà ghi đè public void run()phương thức, nó sẽ được thực thi mỗi khi bạn chuyển một thể hiện của lớp đó sangtimer.schedule() phương thức ..

Đây là một ví dụ, in ra Hello Worldcứ sau 5 giây: -

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

9
Lưu ý rằng schedulephương thức 2-param sẽ thực thi một lần sau độ trễ đã chỉ định. 3-param schedulehoặc scheduleAtFixedRatesẽ cần phải được sử dụng.
Tim Bender

2
haha Đôi khi tôi nhận được nhiều phiếu bầu cho câu trả lời và tôi đi tìm thấy rằng sự hiểu biết của chính tôi đã được cải thiện kể từ lần cuối tôi nhầm lẫn thông qua việc cung cấp một giải pháp.
Tim Bender

4
@TimBender Chỉ cần tự hỏi liệu OP có thực sự hoàn thành nhiệm vụ của mình với việc này không;) Dù sao, bây giờ tôi muốn sử dụng ExecutorServicecho các nhiệm vụ này. Đó thực sự là một cải tiến lớn so với API chủ đề truyền thống. Chỉ không sử dụng nó tại thời điểm trả lời.
Rohit Jain

4
Timer timer = new Timer(true);nên được đặt thành truemột deamon. Trừ khi bạn muốn hẹn giờ vẫn chạy sau khi đóng ứng dụng.
Tomasz Mularchot

Điều này cũng giúp tôi cuối cùng cũng khiến tôi hiểu được bộ tính giờ. + 1. Hãy làm tốt công việc!
Daniel Tork

197

Nếu bạn muốn làm một nhiệm vụ định kỳ, sử dụng một ScheduledExecutorService. Cụ thể lên lịchExecutorService.scheduleAtFixedRate

Mật mã:

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

ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(helloRunnable, 0, 3, TimeUnit.SECONDS);

10
Tôi hy vọng ai đó cũng ủng hộ điều này là tốt. Thread.s ngủ () có thể phù hợp với mã trong OP nhất, nhưng đó là một sự tái tạo khá nghiệp dư của bánh xe. Các kỹ sư phần mềm chuyên nghiệp sẽ sử dụng API đã thử và đáng tin cậy, chẳng hạn như TimerTask. Tuy nhiên, lên lịchExecutorService thậm chí còn tốt hơn; tham khảo Thực hành đồng thời Java của Brian Goetz và cộng sự . Lớp thứ hai đã tồn tại được gần một thập kỷ. Thật đáng buồn khi tất cả những câu trả lời khác đều bỏ qua nó.
Michael Scheper

2
@MichaelScheper, Cảm ơn bạn, tôi rất vui khi thấy câu trả lời này cuối cùng đã vượt qua TimerTaskbiến thể. Thật thú vị, tôi nhận thấy rằng câu trả lời được chấp nhận thực sự không chính xác: \ Tuổi của hai API sang một bên, ScheduledExecutorServicechỉ đơn giản là khai báo bằng trực giác hơn. Việc sử dụng TimeUnitnhư là một tham số làm cho nó rõ ràng hơn nhiều những gì đang xảy ra. Đã qua rồi cái thời mã như thế 5*60*1000 // 5 minutes.
Tim Bender

2
@TimBender Tôi nhận thấy bạn có 3 đối số cho khoảng thời gian. Tôi không thể tìm thấy liệu đó là trong vài giây hay một phần nghìn giây. Tôi muốn nó chạy cứ sau 500 mili giây (nửa giây).
JohnMerlino

2
À, tôi hiểu rồi. Đối số thứ tư cho phép bạn chỉ định thời gian, ví dụ TimeUnit.MILLISECONDS.
JohnMerlino

1
@TerryCarter Trong Java8 + Thay vào đó, bạn có thể làm điều Runnable helloRunnable = () -> { /*code */ };đó thậm chí còn đẹp hơn;)
Joel

39

Hãy thử làm điều này:

Timer t = new Timer();
t.schedule(new TimerTask() {
    @Override
    public void run() {
       System.out.println("Hello World");
    }
}, 0, 5000);

Mã này sẽ chạy in để điều khiển Hello World cứ sau 5000 mili giây ( 5 giây). Để biết thêm thông tin, hãy đọc https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html


16

Tôi tìm ra nó với một bộ đếm thời gian, hy vọng nó sẽ giúp. Tôi đã sử dụng một bộ đếm thời gian từ java.util.TimerTimerTasktừ cùng một gói. Xem bên dưới:

TimerTask task = new TimerTask() {

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

Timer timer = new Timer();
timer.schedule(task, new Date(), 3000);

10

Bạn có thể dùng Thread.sleep(3000) bên trong cho vòng lặp.

Lưu ý: Điều này sẽ yêu cầu một try/catchkhối.


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

vòng lặp vô hạn được tạo ra nhiệm vụ lập lịch quảng cáo được cấu hình.


4

Cách dễ nhất là đặt luồng chính để ngủ 3000 mili giây (3 giây):

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!"):
}

Điều này sẽ dừng luồng ít nhất X mili giây. Chuỗi có thể ngủ nhiều thời gian hơn, nhưng điều đó tùy thuộc vào JVM. Điều duy nhất được đảm bảo là luồng sẽ ngủ ít nhất là một phần nghìn giây. Hãy xem Thread#sleeptài liệu:

Làm cho luồng hiện đang thực thi ngủ (tạm dừng thực thi) trong số mili giây đã chỉ định, tùy thuộc vào độ chính xác và chính xác của bộ định thời và bộ lập lịch hệ thống .


Cảm ơn @Luiggi. Java sẽ luôn đảm bảo 3000 ms cho dù tôi chạy máy nào (CPU) phải không?
meiryo

@NandkumarTekale quan tâm đến công phu hơn?
meiryo

4
@meiryo Nó sẽ dừng chuỗi ít nhất X mili giây. Chuỗi có thể ngủ nhiều thời gian hơn, nhưng điều đó tùy thuộc vào JVM. Điều duy nhất được đảm bảo là luồng sẽ ngủ ít nhất là một phần nghìn giây.
Luiggi Mendoza

4
Hãy cẩn thận: nếu đây không phải là một hệ thống thời gian thực, giấc ngủ sẽ có ít nhất 3000 ms, nhưng có thể lâu hơn. Nếu bạn muốn ngủ chính xác 3000 ms, đặc biệt là khi cuộc sống của con người có nguy cơ (dụng cụ y tế, máy bay điều khiển, v.v.), bạn nên sử dụng hệ điều hành thời gian thực.
Kinjal Dixit

1
@meiryo: Luiggi và kinjal giải thích rất hay :)
Nandkumar Tekale

3

Sử dụng java.util.TimerTimer#schedule(TimerTask,delay,period)phương pháp sẽ giúp bạn.

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

2

Đây là cách đơn giản để sử dụng thread trong 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!");
}

1

Những gì ông nói. Bạn có thể xử lý các trường hợp ngoại lệ theo cách bạn thích, nhưng Thread.s ngủ (miliseconds); là con đường tốt nhất để đi.

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

1

Đây là một cách đơn giản khác bằng giao diện Runnable trong Thread Constructor

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


-1

Đối với các ứng dụng nhỏ, sử dụng Timer và TimerTask như Rohit đã đề cập là tốt, nhưng trong các ứng dụng web, tôi sẽ sử dụng Quartz Lập lịch để lên lịch công việc và thực hiện các công việc định kỳ như vậy.

Xem hướng dẫn để lập lịch trình Quartz.


-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();
    }
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.