JAVA 다중 스레드 방법 JOIN 상세 및 실례 코드

JAVA 멀티스레드 조인
자바 개발자에게 다중 스레드는 반드시 숙련되게 응용해야 하는 지식점이어야 한다. 특히 자바 언어를 바탕으로 하는 제품을 개발해야 한다.본고는 Java 다중 스레드의 지식점을 깊이 있게 기술하고 후속 시리즈에서 Java5가 Doug Lea 교수가 제공한 Concurrent와 패키지의 디자인 사상과 구체적인 실현과 응용에 중심을 둘 것이다.
어떻게 해야만 깊이 파고들 수 있을까, 나의 이해는 문제를 가지고 있는 것이지, 범용적으로 보는 것이 아니다.그래서 이 시리즈는 기본적으로 문제를 해결하는 것을 위주로 한다. 물론 나도 독자들이 더 좋은 문제를 해결하는 방안을 제시하고 더 많은 문제를 제기할 수 있기를 바란다.수준이 제한되어 있기 때문에 만약에 잘못된 점이 있으면 여러분이 제기하고 함께 토론해 주십시오. 한 마디로 하면 저는 이 시리즈를 통해 저희가 Java 다중 루틴을 깊이 이해하고 실제 개발한 문제를 해결할 수 있기를 바랍니다.
개발자로서 나는 다중 라인의 기초 지식, 예를 들어 무엇이 라인인지 토론할 필요가 없다고 생각한다.어떻게 만드는지 등은 책과 Google에서 얻을 수 있습니다.이 시리즈는 주로 어떻게 다중 스레드를 깊이 있게 해석하여 우리의 평상시 개발을 돕는가, 예를 들어 스레드 탱크는 어떻게 실현하는가?어떻게 자물쇠 등을 응용합니까? 
(1) Join은 무엇에 쓰입니까?간단한 대답, 동기화, 어떻게 동기화합니까?어떻게 이루어졌어요?다음은 하나하나 대답할 것이다.
Join은 Java 멀티 스레드를 접하면서 이해하지 못했습니다.JDK는 다음과 같이 말합니다.

  join
  public final void join(long millis)throws InterruptedException
  Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
이해가 되시나요?글자 그대로 이 라인이 죽을 때까지 기다린다는 뜻이다. 내 의문은 그 라인, 그 자체의 라인인지 호출된 라인인지, 코드:

package concurrentstudy;
/**
 *
 * @author vma
 */
public class JoinTest {
  public static void main(String[] args) {
    Thread t = new Thread(new RunnableImpl());
    t.start();
    try {
      t.join(1000);
      System.out.println("joinFinish");
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   
    }
  }
}
class RunnableImpl implements Runnable {

  @Override
  public void run() {
    try {
      System.out.println("Begin sleep");
      Thread.sleep(1000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }
}

결과:

Begin sleep
End sleep
joinFinish
알겠지, main 라인이 t.join을 호출할 때, main 라인은 t 라인을 기다리고 대기 시간은 1000이다. 만약에 t 라인이 Sleep 2000이라면.

 public void run() {
    try {
      System.out.println("Begin sleep");
      // Thread.sleep(1000);
      Thread.sleep(2000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }

  }

결과:

Begin sleep
joinFinish
End sleep
즉, main 라인은 1000밀리초만 기다린다. T가 언제 끝나든지 t.join () 라면 코드를 봐라.

public final void join() throws InterruptedException {
  join(0);
  }
그러니까 만약에 t.join () = t.join (0) 0 JDK가 이렇게 말하는 A timeout of 0 means to wait forever는 영원히 기다린다는 뜻인가요?
사실은 t가 끝날 때까지 기다렸다가
이게 어떻게 이루어진 거예요?JDK 코드 보기:

 /**
   * Waits at most <code>millis</code> milliseconds for this thread to 
   * die. A timeout of <code>0</code> means to wait forever. 
   *
   * @param   millis  the time to wait in milliseconds.
   * @exception 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);
    }
  } else {
    while (isAlive()) {
    long delay = millis - now;
    if (delay <= 0) {
      break;
    }
    wait(delay);
    now = System.currentTimeMillis() - base;
    }
  }
  }

사실 Join 방법은 wait를 통해 이루어진다.main 루틴이 t.join을 호출할 때,main 루틴은 루틴 대상 t의 자물쇠 (wait는 이 대상의 자물쇠를 가져오는 것을 의미), 이 대상의wait (대기 시간) 를 호출합니다. 이 대상이main 루틴을 깨울 때까지. 예를 들어 종료할 때까지.
이것은 main 스레드가 t.join을 호출할 때 반드시 스레드 t 대상의 자물쇠를 얻을 수 있어야 한다는 것을 의미한다. 만약 그것을 가져오지 못하면wait를 할 수 없다. 방금 열린 예 t.join(1000)은 main 스레드가 1초를 기다린다는 것을 설명하지 않는다. 만약 그것이 기다리기 전에 다른 스레드가 t 대상의 자물쇠를 얻게 된다면 대기 시간은 1밀리초가 아니다.코드 설명:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package concurrentstudy;
/**
 *
 * @author vma
 */
public class JoinTest {
  public static void main(String[] args) {
    Thread t = new Thread(new RunnableImpl());
    new ThreadTest(t).start();
    t.start();
    try {
      t.join();
      System.out.println("joinFinish");
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   
    }
  }
}
class ThreadTest extends Thread {

  Thread thread;

  public ThreadTest(Thread thread) {
    this.thread = thread;
  }

  @Override
  public void run() {
    holdThreadLock();
  }

  public void holdThreadLock() {
    synchronized (thread) {
      System.out.println("getObjectLock");
      try {
        Thread.sleep(9000);

      } catch (InterruptedException ex) {
       ex.printStackTrace();
      }
      System.out.println("ReleaseObjectLock");
    }

  }
}

class RunnableImpl implements Runnable {

  @Override
  public void run() {
    try {
      System.out.println("Begin sleep");
      Thread.sleep(2000);
      System.out.println("End sleep");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }


  }
}

main 메서드에서 new ThreadTest(t)를 사용합니다.start();실례화된 ThreadTest 스레드 대상은 holdThreadLock() 방법에서synchronized(thread)를 통해 스레드 대상 t의 자물쇠를 가져오고 Sleep(9000) 후에 놓는다. 이것은 main 방법 t.join(1000)을 1초 기다리더라도 ThreadTest 스레드가 t자물쇠를 풀어야 wait 방법에 들어갈 수 있다는 것을 의미한다. 실제 대기 시간은 9000+1000MS이다
실행 결과:

getObjectLock
Begin sleep
End sleep
ReleaseObjectLock
joinFinish
소결:
이 절은 주로join과 JDK의 실현을 깊이 있게 설명한다.
읽어주셔서 감사합니다. 여러분에게 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기