IT박스

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

itboxs 2020. 6. 9. 22:21
반응형

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


이 코드에서 두 조인과 중단은 무엇을 의미합니까? 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 / catch와 관련하여 join()throw 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    

Hope to useful, for more detail click here


When thread tA call tB.join() its causes not only waits for tB to die or tA be interrupted itself but create happens-before relation between last statement in tB and next statement after tB.join() in tA thread.

All actions in a thread happen-before any other thread successfully returns from a join() on that thread.

It means program

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);
    }
}

Always print

>> 1111111111111111111111111 ...

But program

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);
    }
}

Can print not only

>> 0000000000 ... 000000111111111111111111111111 ...

But

>> 00000000000000000000000000000000000000000000 ... 

Always only '0'.

Because Java Memory Model don't require 'transfering' new value of 'sharedVar' from threadB to main thread without heppens-before relation (thread start, thread join, usage of 'synchonized' keyword, usage of AtomicXXX variables, etc).


From oracle documentation page on Joins

The join method allows one thread to wait for the completion of another.

If t1 is a Thread object whose thread is currently executing,

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

If t2 is a Thread object whose thread is currently executing,

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

join API is low level API, which has been introduced in earlier versions of java. Lot of things have been changed over a period of time (especially with jdk 1.5 release) on concurrency front.

You can achieve the same with java.util.concurrent API. Some of the examples are

  1. Using invokeAll on ExecutorService
  2. Using CountDownLatch
  3. Using ForkJoinPool or newWorkStealingPool of Executors(since java 8)

Refer to related SE questions:

wait until all threads finish their work in java


Simply put:
t1.join() returns after t1 is completed.
It doesn't do anything to thread t1, except wait for it to finish.
Naturally, code following t1.join() will be executed only after t1.join() returns.


For me, Join() behavior was always confusing because I was trying to remember who will wait for whom. Don't try to remember it that way.

Underneath, it is pure wait() and notify() mechanism.

We all know that, when we call wait() on any object(t1), calling object(main) is sent to waiting room(Blocked state).

Here, main thread is calling join() which is wait() under the covers. So main thread will wait until it is notified. Notification is given by t1 when it finishes it's run(thread completion).

After receiving the notification, main comes out of waiting room and proceeds it's execution.


Hope it helps!

package join;

public class ThreadJoinApp {

    Thread th = new Thread("Thread 1") {
        public void run() {
            System.out.println("Current thread execution - " + Thread.currentThread().getName());
            for (int i = 0; i < 10; i++) {
                System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
            }
        }
    };

    Thread th2 = new Thread("Thread 2") {
        public void run() {
            System.out.println("Current thread execution - " + Thread.currentThread().getName());

            //Thread 2 waits until the thread 1 successfully completes.
            try {
            th.join();
            } catch( InterruptedException ex) {
                System.out.println("Exception has been caught");
            }

            for (int i = 0; i < 10; i++) {
                System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
            }
        }
    };

    public static void main(String[] args) {
        ThreadJoinApp threadJoinApp = new ThreadJoinApp();
        threadJoinApp.th.start();
        threadJoinApp.th2.start();
    }

    //Happy coding -- Parthasarathy S
}

let's say our main thread starts the threads t1 and t2. Now, when t1.join() is called, the main thread suspends itself till thread t1 dies and then resumes itself. Similarly, when t2.join() executes, the main thread suspends itself again till the thread t2 dies and then resumes.

So, this is how it works.

Also, the while loop was not really needed here.

참고URL : https://stackoverflow.com/questions/15956231/what-does-this-thread-join-code-mean

반응형