ฉันได้รับข้อยกเว้นเมื่อใช้ Thread.sleep (x) หรือรอ ()


343

ฉันได้ลองล่าช้า - หรือพัก - โปรแกรม Java ของฉัน แต่มีข้อผิดพลาดเกิดขึ้น

ฉันไม่สามารถที่จะใช้หรือThread.sleep(x) wait()ข้อความแสดงข้อผิดพลาดเดียวกันปรากฏขึ้น:

ข้อยกเว้นที่ไม่ได้ถูกรายงาน java.lang.InterruptedException; ต้องถูกจับหรือประกาศว่าถูกโยน

จำเป็นต้องมีขั้นตอนใดบ้างก่อนใช้Thread.sleep()หรือwait()วิธีการ?


8
นี่เป็นที่นิยม จะต้องมีคนจำนวนมากที่ต้องชะลอการใช้งานโปรแกรม Java ของพวกเขาเป็นเวลาสองสามวินาที ยากที่จะจินตนาการ แน่นอนว่าการใส่ชื่อที่ถูกต้องในโพสต์จะช่วยได้อย่างมาก
Robert Harvey

คำตอบ:


575

คุณมีคนอ่านเยอะมาก จากข้อผิดพลาดของคอมไพเลอร์ผ่านการจัดการข้อยกเว้นการขัดจังหวะการทำเกลียวและเธรด แต่จะทำสิ่งที่คุณต้องการ:

try {
    Thread.sleep(1000);                 //1000 milliseconds is one second.
} catch(InterruptedException ex) {
    Thread.currentThread().interrupt();
}

1
ขอบคุณสำหรับความช่วยเหลือของคุณฉันสามารถเรียกใช้ .. นอกจากสิ่งที่ใช้สำหรับจับ (ขัดจังหวะยกเว้นอดีต)
vincent low

4
ดูคำตอบจาก Abel Google เพื่อการขัดจังหวะยกเว้น ทำเรื่องสั้นให้สั้น: เธรดสามารถถูกขัดจังหวะขณะหลับและนี่เป็นข้อยกเว้นชนิดหนึ่งซึ่งจำเป็นต้องได้รับการจัดการอย่างชัดเจน
Konrad Garus

8
บางคำตอบบอกว่าอย่าทำอะไรเลยยกเว้นบางคนบอกว่าจะโยนนี่เป็นการบอกให้ขัดจังหวะ () มีใครสนใจที่จะอภิปรายว่าเรื่องไหนเหมาะสมและทำไม?
Suma

6
@Suma มีการสนทนามากมายรวมทั้ง Stack Overflow ด้วย เพียงแค่ค้นหามัน ยาวเกินไปสำหรับความคิดเห็น หลังจากไม่กี่ปีคำตอบเดียวที่ฉันมีคือ: ขึ้นอยู่กับ โดยปกติแล้วทางออกที่ดีที่สุดคือการยุติสิ่งที่เธรดกำลังทำอย่างสง่างาม (เช่นย้อนกลับการทำธุรกรรมนี้การแบ่งลูปเป็นต้น) แต่ขึ้นอยู่กับบริบท
Konrad Garus

ดังนั้นเวลาสำหรับอะไร คุณสามารถใช้ฟังก์ชั่นเดียวกันกับตัวจับเวลาได้หรือไม่? ฉันอ่าน java doc และมันพูดถึงบางอย่างเกี่ยวกับความล่าช้า แต่เป็นมือใหม่ที่มีรหัสฉันกำลังจะเสร็จสิ้นการเขียนโปรแกรมชั้นมัธยมปีที่สองของฉันฉันไม่แน่ใจว่าการล่าช้าที่พูดถึงจะเป็นประโยชน์หรือไม่ คลาสที่เหมาะสำหรับการใช้
Ungeheuer

195

อย่างที่ผู้ใช้คนอื่นบอกว่าคุณควรtry{...} catch{...}ปิดกั้นการโทรด้วยบล็อก แต่เนื่องจาก Java 1.5 ออกมามีคลาส TimeUnit ซึ่งทำเช่นเดียวกันกับThread.sleep (มิลลิวินาที)แต่สะดวกกว่า คุณสามารถเลือกหน่วยเวลาสำหรับการนอนหลับ

try {
    TimeUnit.NANOSECONDS.sleep(100);
    TimeUnit.MICROSECONDS.sleep(100);
    TimeUnit.MILLISECONDS.sleep(100);
    TimeUnit.SECONDS.sleep(100);
    TimeUnit.MINUTES.sleep(100);
    TimeUnit.HOURS.sleep(100);
    TimeUnit.DAYS.sleep(100);
} catch (InterruptedException e) {
    //Handle exception
}

นอกจากนี้ยังมีวิธีการเพิ่มเติม: TimeUnit Oracle Documentation


6
ดูคำตอบอื่น ๆ สำหรับตัวอย่างวิธีการล้อมสายเหล่านี้ด้วยการtry-catchจัดการข้อยกเว้นที่จำเป็น
Basil Bourque

2
อย่าลืม "import java.util.concurrent.TimeUnit;"
coder


13

ใช้โครงสร้างการเข้ารหัสต่อไปนี้เพื่อจัดการข้อยกเว้น

try {
  Thread.sleep(1000);
} catch (InterruptedException ie) {
    //Handle exception
}

8

ใส่Thread.sleepบล็อกลองของคุณ

try {
    //thread to sleep for the specified number of milliseconds
    Thread.sleep(100);
} catch ( java.lang.InterruptedException ie) {
    System.out.println(ie);
}

7

เมื่อใช้Android (ครั้งเดียวเมื่อฉันใช้ Java) ฉันอยากจะแนะนำให้ใช้ตัวจัดการแทนการวางกระทู้ให้หลับ

final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            Log.i(TAG, "I've waited for two hole seconds to show this!");

        }
    }, 2000);

อ้างอิง: http://developer.android.com/reference/android/os/Handler.html


4
นี่สำหรับ Android ไม่ใช่สำหรับ Core Java
Ganesh Krishnan เมื่อ

3

ลองสิ่งนี้:

try{

    Thread.sleep(100);
}catch(Exception e)
{
   System.out.println("Exception caught");
}

8
การฝึกจับExceptionจาวาเป็นเรื่องที่ผิดหรือเปล่า?
Michael Dorst

2
จับการขัดจังหวะที่ดีขึ้นเช่นเดียวกับคำตอบอื่น ๆ ที่นี่
devsaw

6
สิ่งนี้เรียกว่า 'Pokemon Exception Handler' - ต้องจับเลย
James Tayler

3

วิธีเพิ่มความล่าช้าในโปรแกรม Java ของฉัน

public void pause1(long sleeptime) {
    try {
        Thread.sleep(sleeptime);
    } catch (InterruptedException ex) {
        //ToCatchOrNot
    }
}

public void pause2(long sleeptime) {
    Object obj = new Object();
    if (sleeptime > 0) {
        synchronized (obj) {
            try {
                obj.wait(sleeptime);
            } catch (InterruptedException ex) {
                //ToCatchOrNot
            }
        }
    }
}
public void pause3(long sleeptime) {
    expectedtime = System.currentTimeMillis() + sleeptime;
    while (System.currentTimeMillis() < expectedtime) {
        //Empty Loop   
    }
}

สิ่งนี้มีไว้สำหรับการหน่วงเวลาตามลำดับ แต่สำหรับการหน่วงเวลาแบบวนซ้ำอ้างอิงถึงJava Delay / Wait


โปรดทราบว่าไม่อนุญาตให้ทำการโปรโมตตนเองอย่างโจ่งแจ้ง ดูจุดสุดท้ายที่นี่ในศูนย์ช่วยเหลือ อย่างไรก็ตามคุณสามารถใส่ลิงค์ในโปรไฟล์ของคุณ - ที่ได้รับอนุญาต
SL Barth - Reinstate Monica

3
public static void main(String[] args) throws InterruptedException {
  //type code


  short z=1000;
  Thread.sleep(z);/*will provide 1 second delay. alter data type of z or value of z for longer delays required */

  //type code
}

เช่น:-

class TypeCasting {

  public static void main(String[] args) throws InterruptedException {
    short f = 1;
    int a = 123687889;
    short b = 2;
    long c = 4567;
    long d=45;
    short z=1000;
    System.out.println("Value of a,b and c are\n" + a + "\n" + b + "\n" + c + "respectively");
    c = a;
    b = (short) c;
    System.out.println("Typecasting...........");
    Thread.sleep(z);
    System.out.println("Value of B after Typecasting" + b);
    System.out.println("Value of A is" + a);


  }
}

0

วิธีที่ง่ายกว่าในการรอคือการใช้System.currentTimeMillis()ซึ่งส่งคืนจำนวนมิลลิวินาทีตั้งแต่เที่ยงคืนของวันที่ 1 มกราคม 1970 UTC ตัวอย่างเช่นเพื่อรอ 5 วินาที:

public static void main(String[] args) {
    //some code
    long original = System.currentTimeMillis();
    while (true) {
        if (System.currentTimeMillis - original >= 5000) {
            break;
        }
    }
    //more code after waiting
}

ด้วยวิธีนี้คุณไม่ต้องวุ่นวายกับหัวข้อและข้อยกเว้น หวังว่านี่จะช่วยได้!


สิ่งนี้กิน CPU ในขณะที่รอ
yacc

@yacc นี่เป็นความจริง แต่มันง่ายกว่าการใช้เธรดและไม่ใช้ CPU มากเกินไป
Sam

0

การใช้java.util.concurrent.TimeUnit:

TimeUnit.SECONDS.sleep(1);

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

TimeUnit.MINUTES.sleep(1);

นอนประมาณหนึ่งนาที

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

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

สำหรับการเรียกใช้งานทุก ๆ วินาทีหรืออย่างช้า ๆ หนึ่งวินาทีฉันขอแนะนำ [ ScheduledExecutorService] [1] และ [ scheduleAtFixedRate] [2] หรือ [ scheduleWithFixedDelay] [3]

ในการรันเมธอด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");
}

0

Thread.sleep() ง่ายสำหรับผู้เริ่มต้นและอาจเหมาะสมสำหรับการทดสอบหน่วยและการพิสูจน์แนวคิด

แต่โปรดอย่าใช้sleep()สำหรับรหัสการผลิต ในที่สุดsleep()อาจกัดคุณไม่ดี

วิธีปฏิบัติที่ดีที่สุดสำหรับแอ็พพลิเคชัน java แบบมัลติเธรด / มัลติคอร์เพื่อใช้แนวคิด "thread wait" รอการปลดล็อกและจอภาพทั้งหมดที่อยู่ในเธรดซึ่งอนุญาตให้เธรดอื่นได้รับจอภาพเหล่านั้นและดำเนินการต่อในขณะที่เธรดของคุณกำลังนอนหลับอย่างสงบ

รหัสด้านล่างแสดงให้เห็นถึงเทคนิคที่:

import java.util.concurrent.TimeUnit;
public class DelaySample {
    public static void main(String[] args) {
       DelayUtil d = new DelayUtil();
       System.out.println("started:"+ new Date());
       d.delay(500);
       System.out.println("half second after:"+ new Date());
       d.delay(1, TimeUnit.MINUTES); 
       System.out.println("1 minute after:"+ new Date());
    }
}

DelayUtil การดำเนินงาน:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class DelayUtil {
    /** 
    *  Delays the current thread execution. 
    *  The thread loses ownership of any monitors. 
    *  Quits immediately if the thread is interrupted
    *  
    * @param durationInMillis the time duration in milliseconds
    */
   public void delay(final long durationInMillis) {
      delay(durationInMillis, TimeUnit.MILLISECONDS);
   }

   /** 
    * @param duration the time duration in the given {@code sourceUnit}
    * @param unit
    */
    public void delay(final long duration, final TimeUnit unit) {
        long currentTime = System.currentTimeMillis();
        long deadline = currentTime+unit.toMillis(duration);
        ReentrantLock lock = new ReentrantLock();
        Condition waitCondition = lock.newCondition();

        while ((deadline-currentTime)>0) {
            try {
                lock.lockInterruptibly();    
                waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            } finally {
                lock.unlock();
            }
            currentTime = System.currentTimeMillis();
        }
    }
}

-2

หรือถ้าคุณไม่ต้องการจัดการกับเธรดลองใช้วิธีนี้:

public static void pause(int seconds){
    Date start = new Date();
    Date end = new Date();
    while(end.getTime() - start.getTime() < seconds * 1000){
        end = new Date();
    }
}

มันเริ่มต้นเมื่อคุณเรียกมันและสิ้นสุดลงเมื่อจำนวนวินาทีผ่านไป


7
สิ่งนี้จะใช้ CPU ในช่วงเวลาพักเครื่อง บน Thread.sleep () สามารถยกเลิกการกำหนดเธรดได้
Vivek Pandey

คุณเป็นคนดีและไม่มีน้ำ: D
M410

17
user2276378 เข้าใจผิดภาษาอังกฤษของคำถาม OP กล่าวว่าเขา "ไม่สามารถใช้โหมดสลีหรือรอ" ซึ่งผู้ใช้ 2276378 คิดว่าหมายความว่าเขาไม่สามารถใช้งานได้ (หรือไม่ได้รับอนุญาตให้ใช้) และดังนั้นเขาจึงจัดหาวิธีแก้ปัญหาที่ถูกต้องซึ่งไม่ได้ใช้โหมดสลีป พยายามอย่าเข้มงวดภาษาอังกฤษไม่ใช่ภาษาแรกของทุกคน
David Newcomb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.