2011-03-01 3 views
6

수율 방법방법 수익률은 어떻게 작동합니까? 자바 독에서

일시적으로 중지되어 다른 스레드를 실행할 수있게하는 현재 실행중인 스레드 객체가 있다고되어있다.

그리고 캐서린 시에라와 버트 베이츠 SCJP 책은

수율() 할 다시 실행 가능으로 현재 실행중인 스레드 머리를 만들 동일한 우선 순위의 다른 스레드를 할 수 있도록라고 가정 말한다 돌아서 라.

실제로 어떤 방법을 사용하고 있습니까?

+1

I 돈 여기에 질문이 없습니다. 인용 한 문서에 대해 이해하지 못하는 점은 무엇입니까? –

+0

나는 우선 순위가 같은 쓰레드가 우선 순위가 더 높은 쓰레드를 포함하지 않는다고 생각한다. –

+4

메쏘프는 소스 코드가 'public static native void yield();'라고 말한다 : p –

답변

10

멀티 스레드 응용 프로그램이있는 경우 yield은 현재 실행중인 스레드가 실행을 일시 중지하고 대기 상태로 설정되도록합니다. JVM은 이전에 대기 상태에 있었던 다른 스레드의 실행을 시작합니다.

방금 ​​생성 한 동일한 스레드가 기술적으로 다시 시작하도록 예약 할 수 있다고 생각합니다.

나는 아직 야생에서 이것을보고있다. 그래서 나는 피하는 것이 안전하다고 생각합니다.

는 정교하게하려면 :

을 멀티 스레드 환경 스레드에서 예정 JVM의 의지에 오프 스케줄되지하고있다. 따라서 코드에서 yield가 호출되지 않더라도 JVM이이를 결정할 때 스레드는 자동으로 다른 스레드에 양보 할 수 있습니다. 따라서 하나의 프로세싱 코어 만있는 환경에서 멀티 스레딩이 가능합니다.

JVM을 사용하지 않을 경우에도 현재 스레드를 대기 상태로두기 만하면됩니다.

내가 그림을 시도하여야한다

:
시간 동안 2 개 스레드의 실행을 매우 단순화 된 그림입니다 다음 (1 개 코어를 가정) - 당신이 스레드는 의미 '-'을 볼 때마다

Thread\Time 1 2 3 4 5 6 7 8 9 
Thread 1 -----------  -----   ------- 
Thread 2    -------  ----------  ------ 

을 실행 중. ' '은 스레드가 대기 중임을 나타냅니다. 보시다시피 실제로 한 번에 하나의 스레드 만 실행할 수 있습니다. 따라서 1이 실행되는 동안 다른 하나는 대기합니다. 어떤 yield가 의도하는 것은 다른 쓰레드에게 현재 실행중인 쓰레드보다 앞서 실행할 기회를주는 것이다.

+0

+1 나는'yield()'를 스케쥴러에 대한 힌트로 생각하는 것이 항상 유용하다는 것을 알았다. (나는 기술적으로 힌트가 아니라는 것을 알고 있지만, 여러면에서 마치 하나처럼 동작 함을 알고있다.) – biziclop

+0

자바 사양에 따르면'yield()'는 아무 것도 할 수 없다. 강제적으로 yield를 원한다면'Thread.sleep (1)'을 시도해 볼 수있다. 그러나 매우 드문 경우에만 이러한 사용이 보증됩니다. –

+0

@Enno,이 행을 확인 하시겠습니까? "방금 생성 한 동일한 스레드가 기술적으로 다시 시작되도록 예약 할 수 있다고 생각합니다." – jjnguy

1

스레드는 상태 준비 (실행) 가능, 차단 (예 : 일부 IO 대기 완료) 또는 실행 중일 수 있습니다. 이것은, 특정의 구현이보다 많은 상태를 가질지라도, 모든 thread 구현에 공통입니다.

수익은 스레드가 실행 중에서 실행 가능으로 변경되도록하고 스케줄러가 미래에 다시 실행되도록 변경할 때까지 기다립니다. 이것이 SCJP 책에서 의미하는 바입니다.

스레드에 대해서는 javadoc에서 설명한 것처럼 잠시 멈춘 것처럼 보입니다. 그래서 두 진술은 모두 정확합니다.

1

yield()은 스레드가 발생하기를 기다리고 있지만 while(condition){ ...}과 같은 것으로 CPC주기를 차단하고 싶지 않을 때 일반적으로 사용됩니다.yield() 작업 방식은 플랫폼마다 다르며 스레드 스케줄러에 따라 다르므로 특정 방식으로 작동하는 방식에 의존해서는 안됩니다.

1

협동 멀티 태스킹 당시의 것입니다. 어떤 목적을 기다리고,

  1. 이 스레드
  2. 을 끝이 스레드 object.wait() 또는 Thread.sleep 같은 일부 차단 작업이, 일부 IO 작업을 완료 대기 않습니다 기본적인 아이디어는 프로세서까지 하나의 스레드를 실행한다 모니터 또는 유사품.
  3. 이 스레드는 Thread.yield()을 호출합니다.

이러한 경우 스레드 스케줄러는 실행할 다른 스레드를 선택합니다. 따라서 다른 스레드에 공정한이되도록하려면 차단 작업이없는 더 긴 루프에서 정기적으로 yield()으로 전화하십시오. (다른 스레드가 실행 준비가되어 있지 않으면 동일한 스레드가 다시 스케줄되므로 실제 성능 손실이 없습니다.)

현대 VM에서는 스레드 전환이 임의의 지점에서 발생할 수 있으며, 나열된 스레드뿐만 아니라 동시에 실행될 필요가 없으므로 일부 VM은 모두 무시할 수 있습니다 (System.gc()과 유사).

+0

차단 된 IO 및 LockSupport.park가 생략되어 있습니다. 스레드가 복구 될 수 있습니다. – bestsss

+0

@bestsss : IO 차단이 언급되고 ("일부 IO 작업이 완료 될 때까지 대기 중") LockSupport.park가 "또는 이와 유사하게"포함됩니다. 그러나 yield()가 필요할 때이 메서드 (및 클래스)가 아직 존재하지 않았다고 생각합니다. –

+0

ŭlo, 나의 나쁜, IO는 나의 마음에서 멀리 미끄러졌다. LockSupport는 1.5에서 소개되었으며 (이 메서드는 효과적으로'Unsafe.park'를 호출합니다.), Thread.yeild는 Java의 초기부터 사용 가능했습니다. – bestsss

1

yield() 메서드는 응용 프로그램의 모든 우선 순위 스레드가 starvation을 발생시키지 않도록합니다. 예 : 5 개의 스레드가 응용 프로그램에 있으며 모두 동일한 우선 순위입니다. 이제 한 스레드가 실행할 기회를 얻었고이 스레드는 작업을 완료하는 데 너무 오래 걸리므로 다른 스레드는 실행 기회를 얻지 못할 것이라고 가정합니다. 이런 종류의 상황을 피하기 위해 항복()이 있습니다.

1

궁극적으로, 원칙적으로 실행 큐에 다시 작업 자체를 놓고 다음 작업 실행을 할 것 같은 운영 체제 메소드를 호출에 yield() 결과에 대한 호출 (source) :

/** 
    * sys_sched_yield - yield the current processor to other threads. 
    * 
    * This function yields the current CPU to other tasks. If there are no 
    * other threads running on this CPU then this function will return. 
    */ 
SYSCALL_DEFINE0(sched_yield) 
{ 
     /* 
     * lock this runqueue and disable interrupts. 
     */ 
     struct rq *rq = this_rq_lock(); 

     schedstat_inc(rq, yld_count); 
     current->sched_class->yield_task(rq); 

     /* 
      * Since we are going to call schedule() anyway, there's 
      * no need to preempt or enable interrupts: 
      */ 
     __release(rq->lock); 
     spin_release(&rq->lock.dep_map, 1, _THIS_IP_); 
     _raw_spin_unlock(&rq->lock); 
     preempt_enable_no_resched(); 

     schedule(); 

     return 0; 
} 
관련 문제