2013-04-21 3 views
0

을 행동 나는 다음과 같은 코드가 있습니다Thread.sleep를 이상하게

public Move chooseMove(Board board) { 

    // start parallel thread 
    this.tn = new TreeNode(this.myboard, this, null); 
    tn.stop = false; 
    this.curT = (new Thread(tn)); 
    this.curT.start(); 


    try { 
     long startTime = System.currentTimeMillis(); 
     Thread.sleep(4000); 
     System.out.println(System.currentTimeMillis() - startTime); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } finally { 
     tn.stop=true; 
     return getBestMove(); 
    } 
} 

출력은 스레드가 정상적으로보다 더 자고 있다는 것을 의미 5400ms 같은 4000ms보다 훨씬 큰 값이 때로는입니다. 어떤 도움이 필요합니까? 감사합니다. .

편집 : 지정된 지연 후 정확하게 스레드 # 수면 중지 보장이 없음을 알고 있습니다. 그러나 추가 1400ms는 긴 지연입니다. 기본적으로 게임 플레이어 에이전트를 구현 중이며 작업을 실행 한 다음 5 초 후에 서버에 값을 반환해야합니다 (그렇지 않으면 서버가 게임을 종료 함). 서버가 java.util.Timer.schedule (TimerTask 태스크, 긴 지연)을 사용 중입니다. 위의 코드에서 this.curT 인 메인 쓰레드에 concurent를 실행하는 쓰레드는 하나 뿐이므로, 실제로는 멀티 쓰레딩을하지 않아도된다. docs.oracle.com에서

+2

프로세서가 다른 작업을 수행하는 중입니까? 프로세서가 많은 쓰레드 동시 작업으로 인해 정말 과언이 아닐 경우 스레드가 잠시 동안 사이클을 얻을 수 없었습니다. – Gray

+0

얼마나 자주 이런 문제가 발생합니까? 다른 코드없이 절전 호출로 스레드를 실행하십시오. –

+0

하나의 스레드에서 Thread.sleep 만 실행하면 올바르게 작동합니다. 하지만 위의 그림과 같이 실제 코드에서 실행되는 스레드는 2 개뿐입니다. – Mouhyi

답변

2

은 : 수면의

두 오버로드 된 버전이 제공됩니다 나노초에 수면 시간을 지정하는 밀리 초 하나에 수면 시간을 지정 하나. 그러나이 수면 시간은 기본 OS에서 제공하는 기능에 의해 제한되므로 정확하게으로 보장 할 수는 없습니다. 또한 sleep 구간은 인터럽트에 의해 종료 될 수 있습니다. 어쨌든, 당신은 수면을 호출하면 정확히 시간 동안 스레드를 일시 중단한다고 생각할 수 없습니다.

+0

예.하지만 제 경험상 @Vito를 사용합니다. 왜 추가 1400ms를 기다리는 이유에 대한 설명? – Gray

+1

1400ms는 오랜 시간이지만 가비지 콜렉션과 같은 활동이이를 설명 할 수 있습니다.그러나 결론은 Thread.sleep의 일시 중지 시간이 정확하다는 점에 의존 할 수 없다는 것입니다. – DaveH

1

이것은 일반적인 동작이며 Thread#sleep 자바 독에 설명되어 있습니다 : 대상 정밀도와 정확성,

가 지정된 밀리 세컨드 수의 사이 (일시적으로 실행 중단) 잠을 현재 실행중인 스레드 원인 시스템 타이머 및 스케줄러.

이에 따라 Thread#sleep은 매개 변수에 표시된 밀리 초 단위로 스레드 작업을 중단 할 수 있습니다.

1

Thread#sleep에 대한 스레드가 정확히 4 초 동안 잠자기 상태가 된 다음 깨어납니다.
스레드가 깨어나면 OS 스케줄러가 실행 가능 큐에 배치합니다.
다음에 스케쥴러가 선택하면 CPU를 차지할 스레드를 실행하는 이됩니다.
OS마다 다른 OS 스케줄러로 인한 추가 지연 오버 헤드가 있습니다. 이것은 Java과 관련이 없습니다.

+0

OS 스케줄러 실행 가능 큐 우선 순위에 영향을줌으로써 정확히 4 초 후에 스레드가 실행되도록하는 방법이 있습니까? – Mouhyi

+0

당신은'MAX_PRIORITY'를 할당 할 수 있습니다. 그러나 당신이 기대하는 정확한 정밀도를 얻는다고 보장 할 수는 없습니다. 정확히 4 초가 필요하다면'sleep' 대신에 폴링을해야합니다.'sleep'을하면 CPU를 포기합니다 4 초 후에 다시 얻을 것이라는 보장은 없습니다. 스레드가 4 초 안에 * 일어날 것을 보장하지만 그 밖의 것은 없습니다. – Cratylus

+0

"폴링"이란 무엇입니까? – Mouhyi