[해 혹] 스 레 드 대기 와 방출 을 정확하게 이해 합 니 다 (wait / notify)
/**
* A: 50 , B 。
*/
class ThreadA extends Thread{
//
Object oa=null;
ThreadA(Object o){
this.oa=o;
}
// A
public void run(){
// ,
synchronized(oa){
System.out.println("ThreadA is running......");
for(int i=0;i<100;i++){
System.out.println(" ThreadA value is "+i);
if(i==50){
try {
//
Thread.currentThread().wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}//if(i==50)
}//for(int i)
}
}
}
/**
* B: A , , A
*/
class ThreadB extends Thread{
//
Object ob=null;
ThreadB(Object o){
this.ob=o;
}
// B
public void run(){
// ,
synchronized(ob){
System.out.println("ThreadB is running......");
for(int i=0;i<50;i++){
System.out.println(" ThreadB value is "+i);
}
//
notify();
}
}
}
//
public class ThreadTest {
public static void main(String[] args){
Object lock=new Object(); //
ThreadA threada=new ThreadA(lock);
ThreadB threadb=new ThreadB(lock);
threada.start(); // A
threadb.start(); // B
}
}
프로그램 은 매우 간단 하 다. 바로 라인 A, B 를 교체 해서 인쇄 하 는 것 이다.하지만 실행 할 때 두 가지 이상 을 던 집 니 다.
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread not owner
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException: current thread not owner
문 제 는 ThreadA 의 Thread. current Thread (). wait () 입 니 다.ThreadB 의 notify ();올라가다
초보 자 들 은 wait () 를 이해 할 때 현재 스 레 드 를 막 는 것 이 라 고 생각 하기 때문에 Thread. currentThread (). wairt ();보기에 매우 일리 가 있다.하지만 JDK 라 이브 러 리 에서 wait () 와 notify () 방법 은 Thread 류 가 아니 라 Object () 에 있 는 것 으로 밝 혀 졌 는 지 모르겠다.wait 방법의 JDK 문 서 를 자세히 살 펴 보 겠 습 니 다.
public final void wait() throws InterruptedException
다른 스 레 드 에서 이 대상 을 호출 하 는
notify()
방법 이나 notifyAll()
방법 전에 현재 스 레 드 가 기 다 립 니 다.이 방법 은 wait (0) 호출 만 수행 하 는 것 과 같다 는 얘 기다.현재 스 레 드 는 이 대상 모니터 를 가지 고 있어 야 합 니 다.이 스 레 드 는 이 모니터 의 소유권 을 발표 하고 다른 스 레 드 가 호출
notify
방법 이나 notifyAll
방법 으로 이 대상 의 모니터 에서 기다 리 는 스 레 드 가 깨 어 날 때 까지 기 다 립 니 다.그리고 이 스 레 드 는 모니터 에 대한 소유권 을 다시 얻 은 후에 야 계속 실 행 될 것 이다. 특정한 매개 변수의 버 전에 대해 중단 과 허위 각성 을 실현 하 는 것 이 가능 하 며 이 방법 은 항상 순환 에서 사용 해 야 합 니 다.
synchronized (obj) { while (
이 방법 은 이 대상 모니터 의 소유자 스 레 드 로 만 호출 되 어야 합 니 다.
던 지기:
IllegalMonitorStateException
- 현재 스 레 드 가 이 대상 모니터 의 소유자 가 아니라면.InterruptedException
- 현재 스 레 드 가 알림 을 기다 리 기 전이 나 알림 을 기다 리 고 있 을 때 모든 스 레 드 가 현재 스 레 드 를 중단 합 니 다. 이 이상 을 던 졌 을 때 현재 스 레 드 의 중단 상태 가 삭 제 됩 니 다.JDK 문 서 를 보고 시작 한 프로그램 에서 Thread. current Thread (). wait (), oa. wait (), notify (), ob. notify () 로 바 꾸 면 문제 가 없 음 이 분명 합 니 다.
즉, 동기 블록 obj 를 통 해 wait / notify 방법 을 호출 할 수 있 을 뿐, 당연한 스 레 드 를 통 해 이 두 가지 방법 을 호출 할 수 없습니다. 왜 그런 지 에 대해 서 는 한 가지 생각 이 있 습 니 다. 여러분 은 함께 토론 할 수 있 습 니 다.
우선, 우 리 는 JVM 이 모든 대상 에 게 유일한 자 물 쇠 를 분배 할 것 이라는 것 을 알 고 있 습 니 다. 이 자 물 쇠 는 대상 에 있 습 니 다.
그리고 Thread - 0 스 레 드 가 이 자 물 쇠 를 가 져 왔 을 때 대상 의 잠 금 에 현재 자신의 스 레 드 번 호 를 기록 하고 사용 중인 것 으로 설정 해 야 합 니 다. 그러면 Thread - 0 이 자 물 쇠 를 포기 해 야 할 때 잠 금 대상 은 Thread - 0 을 잠 금 대기 열 에 넣 습 니 다. 이 모든 것 은 Thread - 0 과 아무런 관계 가 없습니다. Thread - 0 대상 으로 바 꿀 수도 없습니다.어떤 방법 으로 다른 대상 의 자 물 쇠 를 바 꿔 라.
따라서 공공 데이터 구역 대상 의 자 물 쇠 를 바 꾸 는 방법 은 공 데이터 구역 대상 본 성 을 통 해 호출 되 고 스 레 드 대상 과 관계 가 없다.
사실 모든 동기 화 잠 금 lock 아래 에 준비 (Ready) 대기 열, 대기 (Waiting) 대기 열 등 몇 개의 스 레 드 대기 열 이 걸 려 있 습 니 다. 스 레 드 A 가 동기 화 잠 금 lock 을 얻 지 못 해 lock. Ready Queue (준비 대기 열) 에 들 어 갑 니 다. 동기 화 잠 금 이 점용 되 지 않 으 면 JVM 은 자동 으로 준 비 된 대기 열 에 있 는 스 레 드 를 실행 합 니 다. notify () 가 필요 하지 않 습 니 다.동작 합 니 다. 하지만 스 레 드 A 가 wait () 에 걸 리 면 lock. WaitingQuene (대기 열) 에 들 어 갑 니 다. 동시에 차지 하 는 동기 화 잠 금 도 포기 합 니 다. 이 때 동기 화 잠 금 이 대기 열 에 있 는 프로 세 스 (lock. notify () 를 깨 우지 않 으 면 이 프로 세 스 는 실행 할 기 회 를 얻 지 못 합 니 다.
준비 대기 행렬 과 대기 행렬 이 크게 다르다 는 점 을 명심 하 세 요.
object 의 wait, notify, notify All 에 대한 이 해 는 '자바 가상 컴퓨터 시스템 구조' 의 메모리 저장 소 내용 을 참조 하면 더욱 깊이 이해 할 수 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
간단하게 말하자면, Scala 집합하위 패키지의 모든 정의를 포함합니다.당신이 처리할 대부분의 추상은 여기에 정의되어 있습니다.collection.concurrent매핑 피쳐와 TrieMap 클래스를 정의하려면 원자적이고 잠금 없는 액세스 작업을 사...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.