자바 기본 튜 토리 얼 의 자바 스 레 드 대기 및 자바 깨 우기 스 레 드 자바 다 중 스 레 드 튜 토리 얼
wait(),notify(),notify All()등 방법 은 Object.자바 에서 wait(),notify(),notify All()등 인 터 페 이 스 를 정의 합 니 다.wait()의 역할 은 현재 스 레 드 를 대기 상태 에 들 어가 게 하 는 동시에 wait()도 현재 스 레 드 가 가지 고 있 는 자 물 쇠 를 방출 합 니 다.한편,notify()와 notify All()의 역할 은 현재 대상 의 대기 스 레 드 를 깨 우 는 것 입 니 다.notify()는 하나의 스 레 드 를 깨 우 는 것 이 고 notify All()은 모든 스 레 드 를 깨 우 는 것 입 니 다.
Object 클래스 에서 대기/깨 우기 API 에 대한 자세 한 정 보 는 다음 과 같 습 니 다:notify() -- 이 대상 모니터 에서 기다 리 는 단일 스 레 드 를 깨 웁 니 다.notifyAll() -- 이 대상 모니터 에서 기다 리 는 모든 스 레 드 를 깨 웁 니 다.wait() -- 현재 스 레 드 를'대기(차단)상태'로 만 듭 니 다.'다른 스 레 드 가 이 대상 의 notify()방법 이나 notify All()방법 을 호출 할 때 까지'현재 스 레 드 가 깨 어 납 니 다('준비 상태'로 들 어 갑 니 다).wait(long timeout) -- 현재 스 레 드 를'대기(차단)상태'로 만 듭 니 다.'다른 스 레 드 가 이 대상 의 notify()방법 이나 notify All()방법 을 호출 하거나 지정 한 시간 을 초과 할 때 까지'현재 스 레 드 가 깨 어 납 니 다('준비 상태'로 들 어 갑 니 다).wait(long timeout, int nanos) -- 현재 스 레 드 를'대기(차단)상태'로 합 니 다.'다른 스 레 드 가 이 대상 의 notify()방법 이나 notify All()방법 을 호출 하거나 다른 스 레 드 가 현재 스 레 드 를 중단 하거나 실제 시간 을 초과 할 때 까지'현재 스 레 드 가 깨 어 납 니 다('준비 상태'로 들 어 갑 니 다).
2.wait()와 notify()예제 아래 예제 를 통 해'wait()와 notify()가 함께 사용 하 는 상황'을 보 여 줍 니 다.
// WaitTest.java
class ThreadA extends Thread{
public ThreadA(String name) {
super(name);
}
public void run() {
synchronized (this) {
System.out.println(Thread.currentThread().getName()+" call notify()");
// wait
notify();
}
}
}
public class WaitTest {
public static void main(String[] args) {
ThreadA t1 = new ThreadA("t1");
synchronized(t1) {
try {
// “ t1”
System.out.println(Thread.currentThread().getName()+" start t1");
t1.start();
// t1 notify() 。
System.out.println(Thread.currentThread().getName()+" wait()");
t1.wait();
System.out.println(Thread.currentThread().getName()+" continue");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
실행 결과:
main start t1
main wait()
t1 call notify()
main continue
결 과 는 다음 과 같다.다음 그림 은'메 인 스 레 드'와'스 레 드 t1'의 절 차 를 설명 한다.(01)주의 하 세 요.그림 에서'메 인 스 레 드'는'메 인 스 레 드 main'을 대표 합 니 다.'스 레 드 t1"WaitTest 에서 시 작 된"스 레 드 t1"을 대표 합 니 다.'자물쇠'는't1 이라는 대상 의 동기 자물쇠'를 대표 합 니 다.(02)"메 인 스 레 드"는 new ThreadA("t1")를 통 해"스 레 드 t1"을 새로 만 듭 니 다.그 다음 에 synchronized(t1)를 통 해't1 대상 의 동기 화 자물쇠'를 가 져 옵 니 다.그리고 t1.start()를 호출 하여'스 레 드 t1'을 시작 합 니 다.(03)"메 인 스 레 드"는 t1.wait()를 실행 하여"t1 대상 의 잠 금"을 풀 고"대기(차단)상태"에 들 어 갑 니 다.t1 대상 의 스 레 드 가 notify()나 notify All()을 통 해 깨 어 날 때 까지 기 다 립 니 다.(04)"스 레 드 t1"이 실 행 된 후 synchronized(this)를 통 해"현재 대상 의 자물쇠"를 가 져 옵 니 다.이 어 notify()를 호출 하여'현재 대상 의 대기 스 레 드',즉'메 인 스 레 드'를 깨 웁 니 다.(05)"스 레 드 t1"이 실 행 된 후"현재 대상 의 자물쇠"를 방출 합 니 다.이 어'메 인 스 레 드'는't1 대상 의 자물쇠'를 가 져 온 다음 에 실 행 됩 니 다.
위의 코드 에 대해 서?한 친구 가 물 었 습 니 다.t1.wait()는'스 레 드 t1'을 기다 리 게 해 야 합 니 다.그런데 왜'메 인 스 레 드 main'을 기다 리 게 했 을 까?이 문 제 를 풀기 전에 jdk 문서 에서 wait 에 대한 소 개 를 살 펴 보 겠 습 니 다.
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
In other words, this method behaves exactly as if it simply performs the call wait(0).
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
중국어다른 스 레 드 가 notify()나 notify All()을 호출 하여 이 스 레 드 를 깨 울 때 까지'현재 스 레 드'를 기다 리 게 합 니 다.다시 말 하면 이 방법 은 wait(0)의 효과 와 같다!덧 붙 여 wait(long millis)방법 에 대해 서 는 millis 가 0 일 때 notify()나 notifyAll()에 의 해 깨 어 날 때 까지 무한 기다 림 을 표시 합 니 다."현재 스 레 드 는 wait()를 호출 할 때 이 대상 의 동기 화 잠 금 을 가 져 야 합 니 다.이 스 레 드 는 wait()를 호출 한 후 이 자 물 쇠 를 방출 합 니 다.그리고'다른 스 레 드'가 대상 의 동기 화 잠 금 을 호출 할 때 까지 기다 리 는 notify()나 notify All()방법 입 니 다.그리고 이 스 레 드 는'이 대상 의 동기 화 자물쇠'를 다시 가 져 올 때 까지 기 다 렸 다가 계속 실 행 될 수 있 습 니 다.메모:jdk 의 설명 에서 wait()의 역할 은'현재 스 레 드'를 기다 리 게 하 는 것 이 고,'현재 스 레 드'는 cpu 에서 실행 중인 스 레 드 를 말 합 니 다!t1.wait()는'스 레 드 t1'을 통 해 호출 되 는 wait()방법 이지 만 t1.wait()를 호출 하 는 곳 은'메 인 스 레 드 main'에 있다 는 뜻 이다.주 스 레 드 는'현재 스 레 드',즉 실행 상태 여야 t1.wait()를 실행 할 수 있 습 니 다.그래서 이때 의'현재 스 레 드'는'메 인 스 레 드 main'입 니 다!따라서 t1.wait()는'주 스 레 드'를 기다 리 게 하 는 것 이지'스 레 드 t1'이 아 닙 니 다!
3.wait(long timeout)와 notify()wait(long timeout)는 현재 스 레 드 를'대기(차단)상태'로 만 듭 니 다.'다른 스 레 드 가 이 대상 의 notify()방법 이나 notify All()방법 을 호출 하거나 지정 한 시간 을 초과 할 때 까지'현재 스 레 드 가 깨 어 납 니 다('준비 상태'로 들 어 갑 니 다).다음 예 는 wait(long timeout)가 시간 을 초과 한 상태 에서 스 레 드 가 깨 어 난 상황 을 보 여 주 는 것 입 니 다.
// WaitTimeoutTest.java
class ThreadA extends Thread{
public ThreadA(String name) {
super(name);
}
public void run() {
System.out.println(Thread.currentThread().getName() + " run ");
// , 。
while(true)
}
}
public class WaitTimeoutTest {
public static void main(String[] args) {
ThreadA t1 = new ThreadA("t1");
synchronized(t1) {
try {
// “ t1”
System.out.println(Thread.currentThread().getName() + " start t1");
t1.start();
// t1 notify() notifyAll() , 3000ms ; 。
System.out.println(Thread.currentThread().getName() + " call wait ");
t1.wait(3000);
System.out.println(Thread.currentThread().getName() + " continue");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
실행 결과:
main start t1
main call wait
t1 run // 3 ... “main continue”
main continue
결과 설명:다음 그림 은'메 인 스 레 드'와'스 레 드 t1'의 절 차 를 설명 한다.(01)주의 하 세 요.그림 에서'메 인 스 레 드'는 WaitTimeoutTest 메 인 스 레 드(즉,스 레 드 main)를 대표 합 니 다."스 레 드 t1 은 WaitTest 에서 시 작 된 스 레 드 t1 을 대표 합 니 다.'자물쇠'는't1 이라는 대상 의 동기 자물쇠'를 대표 합 니 다.(02)메 인 스 레 드 main 에서 t1.start()를 실행 하여"스 레 드 t1"을 시작 합 니 다.(03)메 인 스 레 드 main 은 t1.wait(3000)를 실행 합 니 다.이때 메 인 스 레 드 는'차단 상태'에 들 어 갑 니 다."t1 대상 잠 금 에 사용 할 스 레 드 는 notify()또는 notify All()을 통 해 깨 워 야 합 니 다"또는"3000 ms 초과 후"주 스 레 드 main 이"준비 상태"에 들 어가 야 실행 할 수 있 습 니 다.(04)"스 레 드 t1"이 실 행 된 후 순환 에 들 어가 계속 실 행 됩 니 다.(05)3000 ms 를 초과 하면 메 인 스 레 드 main 은'준비 상태'에 들 어간 다음 에'운행 상태'에 들어간다. 4.wait()와 notify All()은 앞의 예 시 를 통 해 notify()가 이 대상 모니터 에서 기다 리 는 단일 스 레 드 를 깨 울 수 있다 는 것 을 알 고 있 습 니 다.다음은 notify All()의 용법 을 예시 로 보 여 줍 니 다.이 대상 모니터 에서 기다 리 는 모든 스 레 드 를 깨 우 는 역할 을 합 니 다.
public class NotifyAllTest {
private static Object obj = new Object();
public static void main(String[] args) {
ThreadA t1 = new ThreadA("t1");
ThreadA t2 = new ThreadA("t2");
ThreadA t3 = new ThreadA("t3");
t1.start();
t2.start();
t3.start();
try {
System.out.println(Thread.currentThread().getName()+" sleep(3000)");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(obj) {
// 。
System.out.println(Thread.currentThread().getName()+" notifyAll()");
obj.notifyAll();
}
}
static class ThreadA extends Thread{
public ThreadA(String name){
super(name);
}
public void run() {
synchronized (obj) {
try {
//
System.out.println(Thread.currentThread().getName() + " wait");
// wait
obj.wait();
//
System.out.println(Thread.currentThread().getName() + " continue");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
실행 결과:
t1 wait
main sleep(3000)
t3 wait
t2 wait
main notifyAll()
t2 continue
t3 continue
t1 continue
결과 설명:아래 의 흐름 도 를 참고 하 세 요.(01)메 인 스 레 드 에 3 개의 스 레 드"t1","t2","t3"를 새로 만 들 고 시작 합 니 다.(02)메 인 스 레 드 는 sleep(3000)을 통 해 3 초 간 휴면 한다.메 인 스 레 드 가 3 초 동안 휴면 하 는 과정 에서 우 리 는't1','t2'와't3'라 는 세 개의 스 레 드 가 모두 실행 되 었 다 고 가정 합 니 다."t1"을 예 로 들 면,실행 할 때,다른 라인 이 notify()나 액 nofityAll()을 통 해 깨 어 날 때 까지 obj.wait()를 실행 합 니 다.같은 이치 로"t2"와"t3"도 다른 스 레 드 가 nofity()나 nofity All()을 통 해 깨 어 나 기 를 기다 리 고 있 습 니 다.(03)메 인 스 레 드 는 3 초 간 휴면 한 후 계속 운행 한다.obj.notifyAll()을 실행 하여 obj 의 대기 스 레 드 를 깨 웁 니 다.즉,"t1","t2","t3"세 스 레 드 를 깨 웁 니 다.이 어 메 인 스 레 드 의 synchronized(obj)가 실 행 된 후 메 인 스 레 드 는"obj 자물쇠"를 방출 합 니 다.이렇게 하면't1','t2'와't3'는'obj 자물쇠'를 가 져 와 계속 실 행 됩 니 다!5.왜 notify(),wait()등 함수 가 Thread 에 있 는 Object 의 wait(),notify()등 함수 가 아 닌 Object 에 정의 되 어 있 는 지,synchronized 와 마찬가지 로'대상 의 동기 화 잠 금'을 작 동 합 니 다.wait()는'현재 스 레 드'를 기다 리 게 합 니 다.스 레 드 가 대기 상태 에 들 어가 기 때문에 스 레 드 는 잠 금 이 가지 고 있 는'동기 잠 금'을 풀 어야 합 니 다.그렇지 않 으 면 다른 스 레 드 가 이'동기 잠 금'을 가 져 오지 못 해 실행 할 수 없습니다!OK.스 레 드 가 wait()를 호출 하면 자물쇠 가 가지 고 있 는'동기 화 자물쇠'를 방출 합 니 다.그리고 앞의 소개 에 따 르 면,우 리 는 대기 라인 이 notify()또는 notify All()에 의 해 깨 어 날 수 있다 는 것 을 알 고 있다.지금,notify()는 무엇 에 근거 하여 대기 라인 을 깨 우 는 것 입 니까?아니면 wait()대기 스 레 드 와 notify()는 무엇 을 통 해 연결 되 어 있 습 니까?정 답 은'대상 의 동기 화 자물쇠'에 따른다.
대기 스 레 드 를 깨 우 는 그 스 레 드(우 리 는'스 레 드 깨 우기'라 고 합 니 다)는'이 대상 의 동기 화 잠 금'(이 동기 화 잠 금 은 대기 스 레 드 의 동기 화 잠 금 과 동일 해 야 합 니 다)을 가 져 오고 notify()나 notify All()방법 을 호출 한 후에 야 대기 스 레 드 를 깨 울 수 있 습 니 다.스 레 드 가 깨 어 날 때 까지 기다 리 지만;그러나 스 레 드 를 깨 우 는 데'이 대상 의 동기 화 자물쇠'가 있 기 때문에 즉시 실행 할 수 없습니다.스 레 드 를 깨 워'대상 의 동기 화 잠 금'을 풀 어 준 후에 스 레 드 를 기 다 려 야'대상 의 동기 화 잠 금'을 얻 고 계속 실행 할 수 있 습 니 다.
한 마디 로 하면 notify(),wait()는'동기 자물쇠'에 의존 하고'동기 자물쇠'는 대상 자물쇠 가 가지 고 있 으 며 대상 마다 하나 밖 에 없습니다!이것 이 바로 notify(),wait()등 함수 가 Thread 클래스 가 아 닌 Object 클래스 에 정 의 된 이유 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
자바 기본 튜 토리 얼 join 방법 자바 다 중 스 레 드 튜 토리 얼 상세 설명2.join()소스 코드 분석(JDK 1.7.0 기반40) 설명:코드 에서 우 리 는 발견 할 수 있다.millis==0 일 때 while(isAlive()순환 에 들 어 갑 니 다.즉,하위 스 레 드 가 살 아 있...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.