Thread.sleep (x) 또는 wait ()를 사용할 때 예외가 발생합니다.


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
도와 주셔서 감사합니다, 나는 그것을 실행할 수 있습니다. 옆에, catch (interruptedException 예)의 용도는 무엇입니까
— 빈센트 낮은

4
Abel의 답변을 참조하십시오. InterruptedException을위한 Google. 간단히 말해 : 잠자는 동안 스레드가 중단 될 수 있으며, 이는 명시 적으로 처리해야하는 일종의 예외입니다.
— Konrad Garus

8
일부 답변은 예외에 대해 아무 것도하지 말라고하고, 일부는 던지라고 말하며, 이것은 인터럽트 ()를 알려줍니다. 누가 어떤 것이 적절한 지, 왜 논의해야합니까?
— 수마

6
@Suma Stack Overflow 자체를 포함하여 그것에 대한 많은 토론이 있습니다. 그냥 찾으십시오. 댓글이 너무 깁니다. 몇 년 후, 내가 가진 유일한 대답은 다음과 같습니다. 일반적으로 이상적인 솔루션은 스레드가 정상적으로 수행하는 모든 작업을 종료하는 것입니다 (예 :이 트랜잭션 롤백, 루프 중단 등). 이는 상황에 따라 매우 다릅니다.
— Konrad Garus

그래서 타이머는 무엇입니까? 타이머로 같은 기능을 수행 할 수 있습니까? 나는 자바 문서를 읽고 지연에 대해 언급했지만 코드가있는 초보자는 고등학교 프로그래밍의 2 학년을 마치려고합니다. 이것이 말하는 지연이 여기에서 유용할지 확실하지 않습니다. 올바른 수업
— Ungeheuer 2016 년

195

다른 사용자가 말했듯이 try{...} catch{...}블록으로 통화를 둘러싸 야한다고 말했습니다 . 그러나 Java 1.5가 출시 된 이후 Thread.sleep (millis) 와 동일 하지만 더 편리한 TimeUnit 클래스 가 있습니다. 수면 작동을위한 시간 단위를 선택할 수 있습니다.

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;"을 잊지 마십시오.
— 코더


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

사용하는 경우 안드로이드 (I 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
이것은 핵심 자바가 아닌 안드로이드를위한 것입니다
— Ganesh Krishnan

3

이 시도:

try{

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

8
ExceptionJava 를 잡는 것이 나쁜 습관이 아닙니까?
— Michael Dorst

2
다른 답변과 마찬가지로 InterruptedException을 더 잘 잡을 수 있습니다
— devsaw

6
이것을 '포켓몬 예외 처리기'라고합니다. 모두 잡아야합니다.
— 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 바스-복원 모니카

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()1970 년 1 월 1 일 자정 이후 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);

1 초 동안 자거나

TimeUnit.MINUTES.sleep(1);

잠을 잔다.

이것이 루프이기 때문에 이것은 고유 한 문제인 드리프트를 나타냅니다. 코드를 실행 한 다음 잠들 때마다 매 초마다 조금씩 표류하게됩니다. 이것이 문제라면를 사용하지 마십시오 sleep.

또한 sleep제어와 관련하여 매우 유연하지 않습니다.

매초 또는 1 초 지연으로 작업을 실행하려면 [ ] [1]과 [ ] [2] 또는 [ ] [3]을 강력히 권장합니다 .ScheduledExecutorServicescheduleAtFixedRatescheduleWithFixedDelay

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 애플리케이션에 대한 모범 사례. 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 2016 년

당신은 ridi이고 물이 없습니다 : D
— M410

17
user2276378이 질문의 영어를 오해했습니다. OP는 자신이 "휴면을 사용할 수 없거나 대기 할 수 없다"고 말하면서 user2276378은 사용할 수 없거나 사용이 불가능하다고 생각하여 수면을 사용하지 않거나 대기하지 않는 유효한 솔루션을 제공했다고 말했다. 너무 가혹하지 않도록 노력하십시오 영어는 모든 사람의 모국어가 아닙니다.
— David Newcomb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.