JAVA 다 중 루틴 중 join()방법의 사용 방법
먼저 결론 을 내 립 니 다.t.join()방법 은 메 인 스 레 드(또는 t.join()의 스 레 드 를 호출 하 는 것)를 대기 탱크 에 들 어가 t 스 레 드 가 실 행 된 후에 야 깨 울 수 있 습 니 다.같은 시각 에 운행 상태 에 있 는 다른 스 레 드 에 영향 을 주지 않 습 니 다.
다음은 분석 과정 이다.
이전에 join()방법 에 대해 서 는 t.join()의 t 를 우선 실행 할 수 있 고 t 가 실 행 된 후에 야 다른 스 레 드 를 실행 할 수 있다 는 것 만 알 고 있 었 습 니 다.스 레 드 간 의 병렬 실행 을 직렬 실행 으로 바 꿀 수 있 습 니 다.
package CSDN;
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ThreadTest t1=new ThreadTest("A");
ThreadTest t2=new ThreadTest("B");
t1.start();
t2.start();
}
}
class ThreadTest extends Thread {
private String name;
public ThreadTest(String name){
this.name=name;
}
public void run(){
for(int i=1;i<=5;i++){
System.out.println(name+"-"+i);
}
}
}
실행 결과:A-1
B-1
B-2
B-3
A-2
B-4
A-3
B-5
A-4
A-5
A 라인 과 B 라인 이 번갈아 실 행 된 것 을 알 수 있다.
그 중에서 join()방법 을 추가 한 후(뒤의 코드 는 ThreadTest 류 의 정 의 를 생략 합 니 다)
package CSDN;
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ThreadTest t1=new ThreadTest("A");
ThreadTest t2=new ThreadTest("B");
t1.start();
t1.join();
t2.start();
}
}
실행 결과:A-1
A-2
A-3
A-4
A-5
B-1
B-2
B-3
B-4
B-5
분명히 t1.join()을 사용 한 후에 B 스 레 드 는 A 스 레 드 가 실 행 된 후에 야 실 행 될 수 있다.주의해 야 할 것 은 t1.join()은 t1.start()가 실 행 된 후에 실행 해 야 효과 가 있다 는 것 이다.또한 t1.join()이 t2.start()에 놓 인 후에 도 교체 집행 이 될 것 이다.그러나 효과 가 없 는 것 은 아니다.이 점 은 나 를 오랫동안 괴 롭 혔 고 다른 블 로 거들 에서 도 본 적 이 없다.
깊이 이해 하기 위해 서 는 먼저 join()의 소스 코드 를 살 펴 보 자.
/**
* Waits for this thread to die.
*
* <p> An invocation of this method behaves in exactly the same
* way as the invocation
*
* <blockquote>
* {@linkplain #join(long) join}{@code (0)}
* </blockquote>
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public final void join() throws InterruptedException {
join(0); //join() join(0)
}
/**
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
*
* <p> This implementation uses a loop of {@code this.wait} calls
* conditioned on {@code this.isAlive}. As a thread terminates the
* {@code this.notifyAll} method is invoked. It is recommended that
* applications not use {@code wait}, {@code notify}, or
* {@code notifyAll} on {@code Thread} instances.
*
* @param millis
* the time to wait in milliseconds
*
* @throws IllegalArgumentException
* if the value of {@code millis} is negative
*
* @throws InterruptedException
* if any thread has interrupted the current thread. The
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0); //join(0) wait(0), wait notify
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
join()방법의 밑바닥 은 wait()방법 으로 이 루어 진 것 임 을 알 수 있다.이 를 통 해 알 수 있 듯 이 join 방법 은 동기 화 방법 이다.메 인 스 레 드 가 t1.join()방법 을 호출 할 때 메 인 스 레 드 는 t1 대상 의 자 물 쇠 를 먼저 얻 었 고 그 다음 에 들 어 가 는 방법 으로 t1 대상 의 wait()방법 을 호출 하여 메 인 스 레 드 를 t1 대상 의 대기 탱크 에 들 어 갔다.이때 A 스 레 드 는 실행 되 고 그 다음 t2.start()가 실행 되 지 않 았 기 때문에 B 스 레 드 도 아직 시작 되 지 않 았 다.A 라인 이 실 행 된 후에 메 인 라인 이 계속 실 행 됩 니 다.t2.start()에 도착 해 야 B 라인 이 실 행 됩 니 다.그 밖 에 join()의 위치 와 역할 의 관계 에 대해 우 리 는 아래 의 예 로 분석 할 수 있다.
package CSDN;
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+" start");
ThreadTest t1=new ThreadTest("A");
ThreadTest t2=new ThreadTest("B");
ThreadTest t3=new ThreadTest("C");
System.out.println("t1start");
t1.start();
System.out.println("t2start");
t2.start();
System.out.println("t3start");
t3.start();
System.out.println(Thread.currentThread().getName()+" end");
}
}
실행 결과main start
t1start
t1end
t2start
t2end
t3start
t3end
A-1
A-2
main end
C-1
C-2
C-3
C-4
C-5
A-3
B-1
B-2
B-3
B-4
B-5
A-4
A-5
A,B,C 와 메 인 스 레 드 가 교체 운행 된다.join()가입 방법 후
package CSDN;
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+" start");
ThreadTest t1=new ThreadTest("A");
ThreadTest t2=new ThreadTest("B");
ThreadTest t3=new ThreadTest("C");
System.out.println("t1start");
t1.start();
System.out.println("t1end");
System.out.println("t2start");
t2.start();
System.out.println("t2end");
t1.join();
System.out.println("t3start");
t3.start();
System.out.println("t3end");
System.out.println(Thread.currentThread().getName()+" end");
}
}
실행 결과:main start
t1start
t1end
t2start
t2end
A-1
B-1
A-2
A-3
A-4
A-5
B-2
t3start
t3end
B-3
main end
B-4
B-5
C-1
C-2
C-3
C-4
C-5
여러 번 의 실험 을 통 해 알 수 있 듯 이 메 인 스 레 드 는 t1.join()방법 에서 멈 추고 A 스 레 드 가 실 행 된 후에 야 t3.start()를 실행 할 수 있 지만 B 스 레 드 의 실행 에 영향 을 주지 않 습 니 다.따라서 t.join()방법 은 메 인 스 레 드 를 대기 탱크 에 들 어가 게 하고 t 스 레 드 가 실 행 된 후에 야 깨 어 날 수 있다 는 결론 을 얻 을 수 있다.같은 시각 에 운행 상태 에 있 는 다른 스 레 드 에 영향 을 주지 않 습 니 다.
PS:join 소스 코드 에 서 는 wait 방법 만 호출 되 고 끝 날 때 notify 를 호출 하지 않 습 니 다.이 는 스 레 드 가 die 일 때 자신의 notify All 방법 을 자동 으로 호출 하여 모든 자원 과 자 물 쇠 를 방출 하기 때 문 입 니 다.
JAVA 다 중 스 레 드 에서 join()방법 을 사용 하 는 방법 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 JAVA 다 중 스 레 드 join()방법 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 객체 작성 및 제거 방법정적 공장 방법 정적 공장 방법의 장점 를 반환할 수 있습니다. 정적 공장 방법의 단점 류 공유되거나 보호된 구조기를 포함하지 않으면 이불류화할 수 없음 여러 개의 구조기 파라미터를 만났을 때 구축기를 고려해야 한다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.