ฉันจะทำให้ล่าช้าใน Java ได้อย่างไร


344

ฉันพยายามทำบางสิ่งใน Java และฉันต้องการบางสิ่งบางอย่างเพื่อรอ / ล่าช้าเป็นเวลาหลายวินาทีในขณะที่วนรอบ

while (true) {
    if (i == 3) {
        i = 0;
    }

    ceva[i].setSelected(true);

    // I need to wait here

    ceva[i].setSelected(false);

    // I need to wait here

    i++;
}

ฉันต้องการสร้างซีเควนเซอร์ขั้นตอนและฉันยังใหม่กับ Java ข้อเสนอแนะใด ๆ


19
Thread.Sleep()ใช้
Tiny

2
พิจารณาใช้ตัวจับเวลา
PeterMmm

2
จุดประสงค์ของการรอคืออะไร? คุณกำลังรอเหตุการณ์บางอย่างที่จะเกิดขึ้น? ตรวจสอบให้แน่ใจว่าคุณเข้าใจวิธีการนอนหลับ ()วิธีการ
artdanil

@ Tiny มันไม่ปลอดภัย
Yousha Aleayoub

12
Thread.sleep(<milisecondsToSleep>)มันเป็นจริง sไม่ควรเป็นตัวพิมพ์ใหญ่
Benjamin

คำตอบ:


678

หากคุณต้องการหยุดชั่วคราวให้ใช้java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

เข้านอนเป็นเวลาหนึ่งวินาทีหรือ

TimeUnit.MINUTES.sleep(1);

เพื่อนอนหลับเป็นเวลาหนึ่งนาที

เนื่องจากนี่คือการวนซ้ำสิ่งนี้นำเสนอปัญหาโดยธรรมชาติ - การดริฟท์ ทุกครั้งที่คุณเรียกใช้รหัสและจากนั้นนอนหลับคุณจะลอยจากการทำงานเล็กน้อยพูดทุกวินาที sleepถ้าเรื่องนี้เป็นปัญหาแล้วไม่ได้ใช้

นอกจากนี้sleepยังไม่ยืดหยุ่นมากเมื่อต้องควบคุม

สำหรับการใช้งานทุกวินาทีหรือที่ล่าช้าหนึ่งวินาทีฉันจะขอแนะนำScheduledExecutorServiceและทั้งหรือscheduleAtFixedRatescheduleWithFixedDelay

ตัวอย่างเช่นการเรียกใช้เมธอดmyTaskทุกวินาที (Java 8):

public static void main(String[] args) {
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(App::myTask, 0, 1, TimeUnit.SECONDS);
}

private static void myTask() {
    System.out.println("Running");
}

และใน Java 7:

public static void main(String[] args) {
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    executorService.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            myTask();
        }
    }, 0, 1, TimeUnit.SECONDS);
}

private static void myTask() {
    System.out.println("Running");
}

1
@Matthew Moisen ฉันไม่สามารถเรียกใช้ตัวอย่าง Java 8 นี้ได้ แอพ :: อะไรกันแน่? โดยการเปลี่ยน myTask () เป็นแลมบ์ดาที่ทำงานได้: Runnable myTask = () -> {... };
comfytoday

2
มันเป็นวิธีการ @comfytoday อ้างอิง - ผมขอแนะนำให้เริ่มต้นด้วยเอกสาร
Boris the Spider

TimeUnit.SECONDS.wait(1)กำลังขว้างปาIllegalMonitorStateExceptionใน Java 8.1 build 31 บน Windows 6.3 ฉันสามารถใช้Thread.sleep(1000)โดยไม่ต้องลอง / จับแทน
John Meyer

1
ใน Java 8 ใน java.util.concurrent.TimeUnit คุณจะได้รับUnhandled exception: java.lang.InterruptedExecutionสำหรับsleep(1)
Shai Alon

1
คุณต้องล้อมรอบTimeUnit.SECONDS.sleep(1);ด้วยtry catch
Shai Alon

148

ใช้Thread.sleep(1000);

1000 คือจำนวนมิลลิวินาทีที่โปรแกรมจะหยุดชั่วคราว

try
{
    Thread.sleep(1000);
}
catch(InterruptedException ex)
{
    Thread.currentThread().interrupt();
}

5
อย่าลืมเข้าสู่ระบบ InterruptedException ไม่เช่นนั้นคุณจะไม่มีทางรู้ว่าเธรดนี้ถูกขัดจังหวะ
m0skit0

12
ฉันอยากรู้ว่า Thread.currentThread (). interrupt (); ทำที่นี่
Brent212

1
ดู: "ทำไมเราต้องขัดจังหวะเธรดอีกครั้ง" ที่นี่: javaspecialists.eu/archive/Issue056.html
Tristan


5

ใช้สิ่งนี้:

public static void wait(int ms){
        try
        {
            Thread.sleep(ms);
        }
        catch(InterruptedException ex)
        {
            Thread.currentThread().interrupt();
        }
    }

จากนั้นคุณสามารถเรียกวิธีนี้ได้ทุกที่เช่น:

        wait(1000);

3

การใช้TimeUnit.SECONDS.sleep(1);หรือThread.sleep(1000);เป็นวิธีที่ยอมรับได้ ในทั้งสองกรณีคุณต้องจับInterruptedExceptionซึ่งทำให้โค้ดของคุณ Bulky.There เป็นไลบรารี java แบบโอเพ่นซอร์สที่เรียกว่า MgntUtils (เขียนโดยฉัน) ที่ให้บริการยูทิลิตี้ที่เกี่ยวข้องกับInterruptedExceptionภายในอยู่แล้ว ดังนั้นรหัสของคุณจะรวมหนึ่งบรรทัด:

TimeUtils.sleepFor(1, TimeUnit.SECONDS);

ดู Javadoc ที่นี่ คุณสามารถเข้าถึงห้องสมุดจากMaven กลางหรือจากGithub บทความอธิบายเกี่ยวกับห้องสมุดสามารถพบได้ที่นี่


2
การใช้ catch (InterruptedException e) { /* empty */ }เป็นไม่เป็นทางออกที่เหมาะสมที่นี่ อย่างน้อยที่สุดคุณควรให้ข้อมูลบันทึกบางอย่าง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้โปรดดูjavaspecialists.eu/archive/Issue056.html
Marco13

3

ใช้ Thread.sleep(100);ใช้หน่วยเวลาเป็นมิลลิวินาที

ตัวอย่างเช่น:

public class SleepMessages {
    public static void main(String args[])
        throws InterruptedException {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        for (int i = 0;
             i < importantInfo.length;
             i++) {
            //Pause for 4 seconds
            Thread.sleep(4000);
            //Print a message
            System.out.println(importantInfo[i]);
        }
    }
}

1

ฉันรู้ว่านี่เป็นโพสต์เก่ามาก แต่นี่อาจช่วยใครซักคน: คุณสามารถสร้างวิธีการได้ดังนั้นเมื่อใดก็ตามที่คุณต้องการหยุดชั่วคราวคุณสามารถพิมพ์pause(1000)หรือค่ามิลลิวินาทีอื่น ๆ :

public static void pause(int ms) {
    try {
        Thread.sleep(ms);
    } catch (InterruptedException e) {
        System.err.format("IOException: %s%n", e);
    }
}

สิ่งนี้จะแทรกอยู่เหนือpublic static void main(String[] args)ภายในชั้นเรียน จากนั้นเมื่อต้องการเรียกใช้เมธอดให้พิมพ์pause(ms)แต่แทนที่msด้วยจำนวนมิลลิวินาทีเพื่อหยุดชั่วคราว ด้วยวิธีนี้คุณไม่จำเป็นต้องแทรกคำสั่ง try-catch ทั้งหมดเมื่อใดก็ตามที่คุณต้องการหยุดชั่วคราว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.