yield()의 주요 용도는 무엇이며 join() 및 interrupt()와는 어떻게 다릅니까?
자바에서의 메서드 사용, 특히 아래 코드 예시에서는 조금 혼란스럽습니다.또, 「surve()는 스레드의 실행을 막기 위해서 사용됩니다」라고 하는 것도 읽어 보았습니다.
질문은 다음과 같습니다.
는 두 모두 사용 시 수 생각합니다.
yield()
츠미야거맞 ??'우리'의 주요
yield()
「 」는 입니까?
yield()
join()
★★★★★★★★★★★★★★★★★」interrupt()
방??
코드 예는 다음과 같습니다.
public class MyRunnable implements Runnable {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable());
t.start();
for(int i=0; i<5; i++) {
System.out.println("Inside main");
}
}
public void run() {
for(int i=0; i<5; i++) {
System.out.println("Inside run");
Thread.yield();
}
}
}
하여 같은 수 시에도 ).yield()
:
Inside main
Inside main
Inside main
Inside main
Inside main
Inside run
Inside run
Inside run
Inside run
Inside run
출처 : http://www.javamex.com/tutorials/threads/yield.shtml
창문들
에서는, 「」의 .
Thread.yield()
자바 5 자바 65, Java 5의 경우
Thread.yield()
를 호출하다Sleep(0)
이렇게 하면 현재 스레드의 퀀텀을 클리어하고 큐의 끝에 priority 레벨을 지정하는 특별한 효과가 있습니다.즉, 같은 priority(및 priority가 높은 스레드)의 실행 가능한 모든 스레드에는 다음에 CPU 시간이 지정되기 전에 실행할 기회가 주어집니다.결국 다시 일정이 잡히면 완전한 양자 상태로 돌아오지만, 항복 시점부터 남은 양자 중 어느 것도 "승계"하지 않는다.이 동작은 일반적으로 슬립 스레드가 1개의 양자 값을 잃는 비제로 슬립과는 조금 다릅니다(실제로 10ms 또는 15ms의 1/3).Java 6 서 java java java java java java java java java java java java java java java 。 핫스팟 이 VM을 구현합니다.
Thread.yield()
의SwitchToThread()
API 호출이 호출에 의해 현재 스레드는 현재 타임슬라이스를 포기하지만 전체 퀀텀은 포기되지 않습니다.즉, 다른 스레드의 우선순위에 따라 산출된 스레드는 한 인터럽트 기간 후에 다시 스케줄링할 수 있습니다.(타임라이스에 대한 자세한 내용은 스레드스케줄링 섹션을 참조해 주세요).리눅스
(Hotspot)를 호출합니다.
sched_yield()
에서보다 더 수
- 출력된 스레드는 다른 모든 스레드에 CPU 슬라이스가 할당될 때까지 다른 CPU 슬라이스를 얻을 수 없습니다.
- (적어도 커널 2.6.8 이후에서는) 스레드가 산출된 사실은 스케줄러의 최근 CPU 할당에 대한 휴리스틱에 의해 암묵적으로 고려됩니다.따라서 산출된 스레드는 미래에 스케줄 되었을 때 더 많은 CPU가 할당될 수 있습니다.
(priority 및 스케줄링 알고리즘에 대한 자세한 내용은 스레드스케줄링 섹션을 참조해 주세요).
「 」를
yield()
난 사실상 절대 안 된다고 말하고 싶다.이 동작은 표준으로 정의되어 있지 않으며 일반적으로 yield()를 사용하여 수행할 수 있는 작업을 수행할 수 있는 더 나은 방법이 있습니다.
현상금과 함께 질문이 다시 활성화 되었군요. 이치노yield
제 경험에서 한 가지 예를 들어보겠습니다.
yield
는 다른 스레드를 실행하도록 스케줄링할 수 있도록 호출 스레드가 실행 중인 프로세서를 강제로 포기하도록 합니다.이 기능은 현재 스레드가 작업을 완료했지만 큐의 맨 앞으로 빠르게 돌아가 어떤 조건이 변경되었는지 확인하는 경우에 유용합니다.것은은릅릅릅릅릅릅릅릅릅릅릅? yield
를 사용하면 스레드가 실행 상태로 훨씬 빨리 돌아갈 수 있습니다.조건 변수에서 대기할 때 스레드는 일시 중단되며 다른 스레드가 계속되어야 한다는 신호를 기다릴 필요가 있습니다. yield
는 기본적으로 "다른 스레드를 실행할 수 있도록 허용하지만 내 상태가 매우 빠르게 변경될 것으로 예상되므로 즉시 업무에 복귀할 수 있습니다."라고 말합니다.이는 상태가 빠르게 변화할 수 있지만 스레드를 일시 중단하면 성능에 큰 영향을 미치는 비지 스피닝을 암시합니다.
하지만 충분히 재잘거렸습니다.구체적인 예가 있습니다.파면 평행 패턴입니다.이 문제의 기본적인 예는 0과 1로 채워진 2차원 배열에서 1s의 개별 "섬"을 계산하는 것입니다."섬"은 수직 또는 수평으로 서로 인접한 셀 그룹입니다.
1 0 0 0
1 1 0 0
0 0 0 1
0 0 1 1
0 0 1 1
여기 2개의 1섬이 있습니다.왼쪽 위, 오른쪽 아래입니다.
간단한 해결책은 어레이 전체에 첫 번째 패스를 하고 1의 값을 증분 카운터로 치환하여 마지막에 각 1을 줄자 순서로 시퀀스 번호로 치환하는 것입니다.
1 0 0 0
2 3 0 0
0 0 0 4
0 0 5 6
0 0 7 8
다음 단계에서는 각 값이 자신과 인접 값의 최소값으로 대체됩니다.
1 0 0 0
1 1 0 0
0 0 0 4
0 0 4 4
0 0 4 4
우리는 이제 우리가 두 개의 섬을 가지고 있다는 것을 쉽게 판단할 수 있다.
병렬로 실행하는 부분은 최소값을 계산하는 단계입니다.상세하게 설명하지 않아도 각 스레드는 인터리브 방식으로 행을 가져오며 위의 행을 처리하는 스레드에 의해 계산된 값에 의존합니다.따라서 각 스레드는 이전 행을 처리하는 스레드보다 약간 늦춰야 하지만 적절한 시간 내에 따라잡아야 합니다.상세한 것에 대하여는, 이 문서를 참조해 주세요.의 사용법에 주의해 주세요.sleep(0)
어느 쪽인가 하면 C에 상당합니다.yield
.
이 경우yield
각 스레드를 차례로 강제로 일시정지하기 위해 사용되었지만 인접 행을 처리하는 스레드는 그 사이에 매우 빠르게 진행되기 때문에 조건 변수는 비참한 선택으로 판명됩니다.
당신이 볼 수 있듯이.yield
매우 세밀한 최적화입니다.잘못된 장소에서 사용하면(예: 거의 변경되지 않는 상황에서 대기하는 등) CPU를 과도하게 사용하게 됩니다.
계속 떠들어 죄송합니다. 제가 확실히 이해했길 바랍니다.
의 차이에 대해서yield()
,interrupt()
그리고.join()
- Java뿐만 아니라 일반적으로:
- 양보: 말 그대로, '양보'는 놓아주고, 포기하고, 항복하는 것을 의미한다.스레드가 생성되면 운영 체제(또는 가상 시스템 등)는 다른 스레드를 대신 스케줄링할 의사가 있음을 나타냅니다.이것은 그것이 너무 중요한 일을 하고 있지 않다는 것을 나타냅니다.하지만 이건 힌트일 뿐 아무런 효과도 보장하지 않습니다.
- 참가:여러 스레드가 일부 핸들, 토큰 또는 엔티티에서 '조인'되면 모든 스레드는 다른 모든 관련 스레드의 실행이 완료될 때까지 기다립니다(완전히 또는 대응하는 조인까지).즉, 스레드들이 모두 작업을 완료했다는 뜻입니다.그 후 이들 스레드 각각은 다른 작업을 계속하도록 스케줄 할 수 있으며, 이러한 모든 작업이 실제로 완료되었다고 가정할 수 있습니다.(SQL Join과 혼동하지 마세요!)
- 중단:하나의 스레드가 sleep, wait, join 등의 스레드를 'poke'하기 위해 사용합니다.이것에 의해, 아마도 중단의 징후와 함께, 재실행이 스케줄 됩니다.(하드웨어 인터럽트와 혼동하지 마세요!)
Java 에 대해서는, 을 참조해 주세요.
참가:
Thread.join 사용방법(여기 StackOverflow)
산출량:
중단:
스레드입니다.interrupt() evil?(여기 StackOverflow)
일단 실제 설명은
현재 실행 중인 스레드 개체를 일시적으로 일시 중지하고 다른 스레드 실행을 허용합니다.
메인 스레드가 루프를 5회 실행한 후run
새로운 스레드의 메서드가 실행되고 있기 때문에 모든 콜이yield
메인 스레드의 루프가 실행된 후에만 발생합니다.
join
스레드가 호출될 때까지 현재 스레드가 중지됩니다.join()
실행이 완료되었습니다.
interrupt
호출되고 있는 스레드가 중단되어 인터럽트가 발생합니다.예외입니다.
yield
그럼 컨텍스트를 다른 스레드로 전환할 수 있으므로 이 스레드는 프로세스의 CPU 사용률 전체를 소비하지 않습니다.
현재 답변은 최신이 아니므로 최근 변경 사항을 고려할 때 수정이 필요합니다.
실제적인 차이는 없다Thread.yield()
6부터 9까지 Java 버전 사이에 있습니다.
TL;DR;
결론은 OpenJDK 소스 코드(http://hg.openjdk.java.net/)에 근거하고 있습니다.
USDT 프로브에 대한 핫스팟 지원(시스템 추적 정보는 dtrace 가이드에 설명되어 있음) 및 JVM 속성을 고려하지 않는 경우ConvertYieldToSleep
소스코드yield()
거의 비슷합니다.아래 설명을 참조하십시오.
Java 9:
Thread.yield()
콜, OS 고유의 방식os::naked_yield()
:
Linux의 경우:
void os::naked_yield() {
sched_yield();
}
Windows 의 경우:
void os::naked_yield() {
SwitchToThread();
}
Java 8 이전 버전:
Thread.yield()
콜, OS 고유의 방식os::yield()
:
Linux의 경우:
void os::yield() {
sched_yield();
}
Windows 의 경우:
void os::yield() { os::NakedYield(); }
당신이 볼 수 있듯이.Thread.yeald()
는 모든 Java 버전에서 동일합니다.
Windows 를 참조해 주세요.os::NakedYield()
JDK 8부터:
os::YieldResult os::NakedYield() {
// Use either SwitchToThread() or Sleep(0)
// Consider passing back the return value from SwitchToThread().
if (os::Kernel32Dll::SwitchToThreadAvailable()) {
return SwitchToThread() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
} else {
Sleep(0);
}
return os::YIELD_UNKNOWN ;
}
Java 9와 Java 8의 Win32 API 존재 여부 추가 확인에서 차이점SwitchToThread()
방법.Java 6에도 같은 코드가 존재합니다.
소스 코드os::NakedYield()
JDK 7은 약간 다르지만 동작은 동일합니다.
os::YieldResult os::NakedYield() {
// Use either SwitchToThread() or Sleep(0)
// Consider passing back the return value from SwitchToThread().
// We use GetProcAddress() as ancient Win9X versions of windows doen't support SwitchToThread.
// In that case we revert to Sleep(0).
static volatile STTSignature stt = (STTSignature) 1 ;
if (stt == ((STTSignature) 1)) {
stt = (STTSignature) ::GetProcAddress (LoadLibrary ("Kernel32.dll"), "SwitchToThread") ;
// It's OK if threads race during initialization as the operation above is idempotent.
}
if (stt != NULL) {
return (*stt)() ? os::YIELD_SWITCHED : os::YIELD_NONEREADY ;
} else {
Sleep (0) ;
}
return os::YIELD_UNKNOWN ;
}
다음 이유로 인해 추가 체크가 폐기되었습니다.SwitchToThread()
메서드는 Windows XP 및 Windows Server 2003부터 사용할 수 있습니다(msdn 노트 참조).
실제로 yield()의 주요 용도는 무엇입니까?
현재 스레드를 중지하고 높은 우선순위로 스레드 실행을 시작할 수 있음을 CPU에 제안합니다.즉, 현재 스레드에 낮은 우선순위 값을 할당하여 더 중요한 스레드를 위한 공간을 확보합니다.
아래 코드는 yield()를 사용할 때와 사용하지 않을 때 모두 동일한 출력이 될 것이라고 생각합니다.이거 맞는건가요?
아니요, 이 둘은 다른 결과를 낳습니다.yield()가 없으면 스레드가 제어되면 'Inside run' 루프가 한 번에 실행됩니다.그러나 수율()을 설정하면 스레드가 제어력을 확보하면 '내부 실행'을 한 번 인쇄한 다음 제어력을 다른 스레드로 넘깁니다.보류 중인 스레드가 없으면 이 스레드가 다시 시작됩니다.따라서 "Inside run"이 실행될 때마다 실행할 다른 스레드를 찾고 사용 가능한 스레드가 없는 경우 현재 스레드는 계속 실행됩니다.
yield()는 join() 및 interrupt() 메서드와 어떤 점에서 다른가요?
yield()는 다른 중요한 스레드에 공간을 주고 join()은 다른 스레드가 실행을 완료할 때까지 대기하며 interrupt()는 현재 실행 중인 스레드를 중단하여 다른 작업을 수행하기 위한 것입니다.
Thread.yield()
를 지정하면 스레드가 "실행 중" 상태에서 "실행 가능" 상태로 바뀝니다.주의: 스레드가 "대기 중" 상태가 되지 않습니다.
Thread.yield();
하단 스레드를 해제합니다.
Thread
OS 스레드를 사용하고 있기 때문에Thread.yield();
하드웨어 스레드를 해방할 수 있습니다.
의 구현이 잘못됨sleep(millis)
public class MySleep {
public static void sleep(long millis) throws InterruptedException {
long start = System.currentTimeMillis();
do {
Thread.yield();
if (Thread.interrupted()) {
throw new InterruptedException();
}
} while (System.currentTimeMillis() - start < millis);
}
}
그리고.join()
public class MyJoin {
public static void join(Thread t) throws InterruptedException {
while (t.getState() != Thread.State.TERMINATED) {
Thread.yield();
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
}
public static void main(String[] args) {
Thread thread = new Thread(()-> {
try {
Thread.sleep(2000);
} catch (Exception e) {
}
});
thread.start();
System.out.println("before");
try {
join(thread);
} catch (Exception e) {
}
System.out.println("after");
}
}
하드웨어 스레드가 1개밖에 없는 경우에도 동작합니다.단,Thread.yield();
이 삭제됩니다.
Thread.yll()
스레드를 호출할 때yield() 메서드에서는 스레드스케줄러는 현재 실행 중인 스레드를 Runnable 상태로 유지하고 priority가 같거나 높은 다른 스레드를 선택합니다.동등하고 높은 priority의 스레드가 없는 경우 발신측 yield() 스레드의 스케줄을 변경합니다.yield 메서드는 스레드를 대기 또는 차단 상태로 만들지 않습니다.Running State에서 Runnable State로 스레드만 만들 수 있습니다.
가입()
스레드 인스턴스에 의해 Join이 호출되면 이 스레드는 현재 실행 중인 스레드에 Joining 스레드가 완료될 때까지 대기하도록 지시합니다.가입은 현재 작업이 완료되기 전에 완료해야 하는 작업에 사용됩니다.
yield()의 주요 용도는 멀티캐스팅어플리케이션을 보류하기 위한 것입니다.
이러한 모든 방법의 차이는 다른 스레드를 실행할 때 slead를 보류하고 그 스레드가 완료된 후 다시 돌아온다는 것입니다.join()은 스레드 실행의 시작을 끝까지 통합하고 그 스레드가 종료된 후 실행할 다른 스레드의 시작을 가져옵니다.interrupt()는 스레드의 실행을 잠시 중지합니다.
언급URL : https://stackoverflow.com/questions/6979796/what-are-the-main-uses-of-yield-and-how-does-it-differ-from-join-and-interr
'programing' 카테고리의 다른 글
JVM이 JIT 컴파일 코드를 캐시하지 않는 이유는 무엇입니까? (0) | 2022.10.27 |
---|---|
MySQL의 로드 데이터 파일에 대한 액세스가 거부되었습니다. (0) | 2022.10.08 |
사전을 JSON으로 변환하는 중 (0) | 2022.10.08 |
MariaDB에서 생성된 열 정의의 사용자 정의 함수? (0) | 2022.10.08 |
인쇄용 if 스테이트먼트를 인라인으로 쓰는 방법 (0) | 2022.10.08 |