[java] 이 스레드 조인 코드는 무엇을 의미합니까?

이 코드에서 두 조인과 중단은 무엇을 의미합니까? t1.join()원인이 t2될 때까지 중지 t1종료?

Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread t2 = new Thread(new EventThread("e2"));
t2.start();
while (true) {
   try {
      t1.join();
      t2.join();
      break;
   } catch (InterruptedException e) {
      e.printStackTrace();
   }
}



답변

이 스레드 조인 코드는 무엇을 의미합니까?

Thread.join()javadocs 메소드 에서 인용하려면 다음을 수행하십시오 .

join() 이 스레드가 죽을 때까지 기다립니다.

예제 코드를 실행하는 스레드가있을 수 있습니다. 아마도 주요 스레드 일 것입니다 .

  1. 기본 스레드는 t1t2스레드를 작성하고 시작합니다 . 두 개의 스레드가 병렬로 실행되기 시작합니다.
  2. 메인 스레드 t1.join()t1스레드가 완료 될 때까지 대기하도록 호출 합니다 .
  3. t1스레드 완료하고 t1.join()주 스레드의 방법으로 돌아갑니다. 전화를 걸기 t1전에 이미 완료 되었을 수 있습니다 join().이 경우 join()전화가 즉시 돌아옵니다.
  4. 메인 스레드 t2.join()t2스레드가 완료 될 때까지 대기하도록 호출 합니다 .
  5. t2스레드 완료 (또는 그이 전에 완료 수도 t1스레드가했던)와 t2.join()메인 스레드의 방법으로 돌아갑니다.

t1t2스레드가 병렬 로 실행 되고 있지만이를 시작한 기본 스레드가 완료되기를 기다려야 계속 진행할 수 있음을 이해해야합니다 . 그것은 일반적인 패턴입니다. 또한,t1 및 / 또는 t2완료 할 수 전에 메인 스레드 호출 join()그들에. 그렇다면 join()기다리지 않고 즉시 돌아옵니다.

t1.join() t1이 종료 될 때까지 t2를 중지시키는 것을 의미합니까?

아니요 호출 t1.join()중인 기본 스레드는 실행을 중지하고 t1스레드가 완료 될 때까지 기다립니다 . t2쓰레드가 병렬로 실행에 의해 영향을받지 않는다 t1거나t1.join() 전혀 호출.

은 try / 캐치의 측면에서,이 join()던졌습니다InterruptedException 는 호출중인 기본 스레드 join()자체가 다른 스레드에 의해 중단 될 수 있음을 의미합니다 .

while (true) {

while루프에 조인을 갖는 것은 이상한 패턴입니다. 일반적으로 첫 번째 조인을 수행 한 다음 두 번째 조인을 수행하여InterruptedException 각 경우에 적절하게 . 루프에 넣을 필요가 없습니다.


답변

이것은 가장 좋아하는 Java 인터뷰 질문입니다.

Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread e2 = new Thread(new EventThread("e2"));
t2.start();

while (true) {
    try {
        t1.join(); // 1
        t2.join(); // 2  These lines (1,2) are in in public static void main
        break;
    }
}

t1.join()t1은 ” 나는 먼저 끝내고 싶다 “와 같은 것을 말한다 . 의 경우도 마찬가지입니다 t2. 누가 시작 t1했거나 t2스레드 (이 경우에는 main메소드) 에 관계없이 main은 작업을 완료 t1하고 t2완료 할 때까지 기다립니다 .

그러나 중요한 점은 아래로주의해야 할, t1그리고 t2스스로 에 관계없이 병렬로 실행 호출 순서에 가입하실 수 있습니다t1t2. 기다려야main/daemon스레드입니다 .


답변

join()스레드가 완료되기를 기다리는 것을 의미합니다. 이것은 차단 방법입니다. 메인 스레드 (을 수행하는 스레드 join())는 작업이 완료 t1.join()될 때까지 줄 을 기다린 t1다음 동일한 작업을 수행합니다 t2.join().


답변

그림은 천 단어의 가치가 있습니다.

    Main thread-->----->--->-->--block##########continue--->---->
                 \                 |               |
sub thread start()\                | join()        |
                   \               |               |
                    ---sub thread----->--->--->--finish    

유용한 정보를 원하시면 여기를 클릭 하십시오


답변

스레드 tA가 tB.join ()을 호출하면 tB가 죽을 때까지 기다리거나 tA 자체가 인터럽트 될뿐만 아니라 tB의 마지막 명령문과 tA 스레드의 tB.join () 뒤의 다음 명령문 사이의 관계 전에 발생합니다.

스레드의 모든 작업은 다른 스레드가 해당 스레드의 join ()에서 성공적으로 반환되기 전에 발생합니다.

프로그램을 의미한다

class App {
    // shared, not synchronized variable = bad practice
    static int sharedVar = 0;
    public static void main(String[] args) throws Exception {
        Thread threadB = new Thread(() -> {sharedVar = 1;});
        threadB.start();
        threadB.join();

        while (true)
            System.out.print(sharedVar);
    }
}

항상 인쇄

>> 1111111111111111111111111 ...

그러나 프로그램

class App {
    // shared, not synchronized variable = bad practice
    static int sharedVar = 0;
    public static void main(String[] args) throws Exception {
        Thread threadB = new Thread(() -> {sharedVar = 1;});
        threadB.start();
        // threadB.join();  COMMENT JOIN

        while (true)
            System.out.print(sharedVar);
    }
}

뿐만 아니라 인쇄 할 수 있습니다

>> 0000000000 ... 000000111111111111111111111111 ...

그러나

>> 00000000000000000000000000000000000000000000 ... 

항상 ‘0’입니다.

Java 메모리 모델은 관계 이전 (스레드 시작, 스레드 조인, ‘synchonized’키워드 사용, AtomicXXX 변수 사용 등)없이 threadB에서 기본 스레드로 ‘sharedVar’의 새로운 값을 ‘전송’할 필요가 없기 때문입니다.


답변

간단히 말하면 완료
t1.join()후 반환 t1됩니다.
thread t1가 끝나기를 기다리는 것을 제외하고 thread에 아무것도하지 않습니다 .
당연히 코드 추적
t1.join()t1.join()반환 후에 만 실행됩니다
.


답변

조인의 Oracle 설명서 페이지에서

join방법을 사용하면 한 스레드가 다른 스레드의 완료를 기다릴 수 있습니다.

t1이 Thread스레드가 현재 실행중인 객체 인 경우

t1.join() : causes the current thread to pause execution until t1's thread terminates.

t2가 Thread스레드가 현재 실행중인 객체 인 경우

t2.join(); causes the current thread to pause execution until t2's thread terminates.

joinAPI는 이전 버전의 Java에서 도입 된 저수준 API입니다. 동시성에서 일정 기간 동안 (특히 jdk 1.5 릴리스에서) 많은 것들이 변경되었습니다.

java.util.concurrent API를 사용하여 동일한 결과를 얻을 수 있습니다. 예제 중 일부는

  1. 사용 invokeAll을을ExecutorService
  2. CountDownLatch 사용
  3. 사용 ForkJoinPool 또는 newWorkStealingPool 의을 Executors(자바 8부터)

관련 SE 질문을 참조하십시오.

모든 스레드가 Java에서 작업을 완료 할 때까지 기다립니다.