thread.start () 대신 Java의 thread.run ()을 언제 호출합니까?


109

thread.run()대신 Java를 언제 호출 thread.start()합니까?


47
내가 thread.start () 메소드 일 때? :)
Bill the Lizard

3
: @blank, 대답은 간단 t.run()실행할 때 t'현재 스레드의 작업을하고 t.start()실행할 때 t스레드의 작업'을 t자체. 아니면 실제 사용 사례를 요구하고 있습니까?
Pacerier 2014 년

2
당신이 바보이고 나중에 호출해야한다는 것을 깨닫기 위해 멀티 스레드 코드를 디버깅하는 데 한 시간을 보내고 싶을 때 start()! 나처럼 ...이 방법은 공개되지 않아야합니다!
Pierre Henry

답변:


113

동시성이 아닌 기능에만 관련된 특정 단위 테스트에서 run ()을 호출 할 수 있습니다.


95

못. run ()을 직접 호출하면 일반 메서드 호출과 마찬가지로 코드가 동 기적으로 (동일한 스레드에서) 실행됩니다.


25
"Never"는 너무 절대적입니다. 항상 새 스레드를 원하지는 않지만 여전히 코드를 실행합니까?
Tomalak

4
하지만이 경우 run () 메서드를 호출하기 위해 새 Thread를 만드는 것은 불필요하게 낭비입니다. Runnable impl을 만들고 해당 스레드에서 실행하거나 새 스레드를 생성하고 시작하는 것이 더 좋습니다.
Scott Bale

1
재 방문하는 중 ... 절대 안된다면, 방법이 공개 된 이유는 무엇입니까?
공백

4
Thread는 Runnable을 구현하기 때문에 공개되어 있습니다. Thread를 하위 클래스로 만들고 run ()을 재정의 할 수 있습니다. 이는 코드를 Runnable에 넣고이를 Thread 생성자에 전달하는 것과 동일한 효과를 갖습니다. 하지만 별도의 Runnable 객체를 사용하는 것이 더 나은 방법입니다. 그럴 경우 더 많은 유연성이 생깁니다 (예 : Executor에 전달하는 등).
Adam Crume

2
현재 작업중인 구체적인 예를 들어 보겠습니다. GUI 또는 명령 줄에서 실행할 수있는 프로그램이 있습니다. GUI의 경우 무거운 작업을 수행하는 객체가 별도의 스레드에서 실행되고 GUI에 업데이트를 전송하기를 원합니다. 명령 줄 모드에서는 별도의 스레드가 필요하지 않습니다.
Edward Falk

27

양식 촬영 코드 스타일 자바 스레드 자주 묻는 질문 :

Q : 스레드의 start () 메서드와 run () 메서드의 차이점은 무엇입니까?

A : Thread 클래스의 별도 start () 및 run () 메서드는 스레드 프로그램을 만드는 두 가지 방법을 제공합니다. start () 메서드는 새 스레드의 실행을 시작하고 run () 메서드를 호출합니다. start () 메서드는 즉시 반환되고 새 스레드는 일반적으로 run () 메서드가 반환 될 때까지 계속됩니다.

Thread 클래스의 run () 메서드는 아무 작업도하지 않으므로 하위 클래스는 두 번째 스레드에서 실행할 코드로 메서드를 재정의해야합니다. Thread가 Runnable 인수로 인스턴스화되면 스레드의 run () 메서드는 대신 새 스레드에서 Runnable 개체의 run () 메서드를 실행합니다.

스레드 프로그램의 특성에 따라 Thread run () 메서드를 직접 호출하면 start () 메서드를 통해 호출하는 것과 동일한 결과를 얻을 수 있지만 후자의 경우 코드는 실제로 새 스레드에서 실행됩니다.


thread's run() method executes the run() method of the Runnable object in the new thread instead.그것은 사실이 아닙니다 (또는 적어도 내 Java 8 소스 코드가 달리 알려줍니다), 불행히도 링크가 끊어진 것처럼 보이므로 대신 여기에 실수를보고합니다.
kajacx

1
@Tomalak, 이것은 질문에 대한 대답이 아닙니다. 질문은 차이를 요구하는 것이 thread.run()아니라 thread.start().
Pacerier 2014 년

24

실행 thread.run()Thread코드가 실행되는 새 파일 을 생성하지 않습니다 . thread.run()코드가 호출 된 현재 스레드에서 코드를 실행합니다.

실행 thread.start()하면 run()메서드가 호출 되는 새 OS 수준 스레드가 생성 됩니다.

본질적으로:

단일 스레드 프로그래밍 → 직접 run()메서드 호출

다중 스레드 프로그래밍 → start()메서드 호출

또한 다른 사람들이 언급했듯이 '테스트'는 run()코드에서 직접 호출 할 수있는 유일한 권장 사례 인 것 같습니다 .


13

이것은 이미 언급되었지만 명확하게하기 위해 run () 메서드를 호출하기 위해 새 Thread 객체를 만드는 것은 불필요하게 비용이 많이 들고 주요 위험 신호가되어야합니다. 그것은 Runnable를 IMPL 등을 만들 수있는 더 나은, 더 분리 설계 어느 것이의 (a)를 호출 그것의 그 원하는 동작, 또는 (b)는 그 Runnable를 가진 새로운 스레드를 생성하고 스레드를 시작 있다면 직접 run () 메소드를.

더 나은 디커플링 Executor을 위해서는 JDK 5 이상에서 인터페이스와 프레임 워크를 확인하십시오 . 이것은 간단히 말해서 작업 실행 (Runnable 인스턴스) 이 실행 되는 방법 (풀의 기존 스레드를 사용하여 새 스레드에서 현재 스레드에서 Runnable을 실행할 수있는 Executor 구현)을 분리 할 수 ​​있도록합니다. 및 기타).


9

전화 thread.start()하면 차례로 전화 thread.run()합니다. 우회 thread.start()하여 직접 가고 싶은 경우를 생각할 수 없습니다.thread.run()


3
테스트하는 동안 내가 생각할 수있는 유일한 합법적 인 경우입니다. 그렇지 않으면 run ()의 내용은 run 또는 다른 방법으로 호출되는 별도의 메서드에 있어야합니다.
Bill the Lizard

9

Thread 클래스 의 개별 start()run()메서드는 스레드 프로그램을 만드는 두 가지 방법을 제공합니다. start()방법은 새 스레드의 실행을 시작하고 호출하는 run()방법을. start()방법은 즉시 반환하고 새로운 스레드는 일반적으로까지 계속 run()방법 돌아갑니다.

Thread 클래스의 run()메서드는 아무 작업도 수행하지 않으므로 하위 클래스는 두 번째 스레드에서 실행할 코드로 메서드를 재정의해야합니다. Thread가 Runnable 인수로 인스턴스화되면 스레드의 run()메서드는 run()대신 새 스레드에서 Runnable 개체 의 메서드를 실행합니다 .

스레드 프로그램의 특성에 따라 Thread run()메서드를 직접 호출하면 start()메서드 를 통한 호출과 동일한 출력이 제공 될 수 있지만 후자의 경우 코드는 실제로 새 스레드에서 실행됩니다.

참고


Tomalak 답변과 동일합니다 !! 어떤 곳에서 참조했다면 그것을 언급하십시오 !!
Barry

The start() method returns immediately and the new thread normally continues until the run() method returns.경우 start()반환 즉시 어떻게 와서는 run()그것에서 자신을 불렀다 주어진 계속 실행start()
KNU

7

질문이 "실행 메서드 대신 스레드 시작 메서드가 직접 호출되는 이유"인 경우 아래 예제 코드로 대답했습니다. 명확 해지기를 바랍니다. 아래 예에서 :

/*
By calling t1.start(), 
we are getting the main calling thread returned immediately 
after the t1.start() called and is ready to proceed for other 
operations.And the thread t1 starts executing the run method of the object r. 
Hence the the output will be:

      I am the main thread , i created thread t1 and had it execute run method, which is currently looping from 0 to 1000000

      I am done executing run method of testThread

*/


/* If we call t1.run() instead of t1.start(), (just replace t1.start() with t1.run() in the code for testing)
 its like a regular method call and the main thread will not return until the run method completes, 
 hence the output will be:

         I am done executing run method of testThread

         I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000

*/


class testThread implements Runnable{

 public void run()
 {
     for(int i=0;i<1000000;i++){} //a simple delay block to clarify.

     System.out.println("I am done executing run method of testThread");

 }  
}

public class mainClass{

   public static void main(String [] args)
    {
          testThread r = new testThread();
          Thread t1 = new Thread(r);
          t1.start();  /* Question is: can we call instead t1.run() */  
          System.out.println("I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000");

    }
}

5

동기식으로 실행하려는 경우. run 메서드를 호출한다고해서 실제로 멀티 스레딩이 제공되지는 않습니다. start 메서드는 run 메서드를 호출하는 새 스레드를 만듭니다.


3

다른 메서드와 마찬가지로 run ()의 내용을 실행하려는 경우. 물론 스레드를 시작하지 마십시오.


3

시작 및 실행 메소드 사용법을 알고 있다고 가정합니다. 즉, 동기 대 비동기; run 메서드는 기능을 테스트하는 데만 사용할 수 있습니다.

또한 어떤 상황에서는 동일한 스레드 클래스를 하나의 실행 메소드와 다른 하나의 시작 메소드가 호출되는 두 개의 서로 다른 객체를 사용하여 동기화 및 비동기 기능 요구 사항이있는 서로 다른 두 위치에서 사용할 수 있습니다.


2

적어도 JVM 1.6에서는 약간의 검사와 실행이 기본적으로 호출됩니다.

 public synchronized void start() {
        /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added 
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
        stop0(throwableFromStop);
    }
    }

    private native void start0();

2

위의 훌륭한 주석에 대한 참고 사항 : 때때로 "start"메소드를 사용하여 다른 스레드를 실행하는 다중 스레드 코드를 작성합니다. 디버깅에 "실행"( "시작 대신)"을 사용하면 코드가 동 기적으로 실행되고 디버깅이 훨씬 쉬워 지므로 훨씬 쉽게 찾을 수 있습니다.


-1
public class TestClass implements Runnable {
    public static void main(String[] args) {
        TestClass tc = new TestClass();

        Thread t1 = new Thread(tc);
        System.out.println("Before Starting Thread " + Thread.currentThread().hashCode());
        t1.start();
        System.out.println("After Starting Thread " + Thread.currentThread().hashCode());
    }

    @Override
    public void run() {
        System.out.println("TestClass Run method is  Running with thread " + Thread.currentThread().hashCode());        
    }
}

안녕하세요 Frnz, 위의 예제를 확인하고 실행하여 t1.start ()로 처음 실행하고 t1.run () 및 chk 해시 코드로 해시 코드를 확인하고 다음에 t1.run () 및 chk 해시 코드를 참조하십시오
Avatar Girase 2015

질문은 어디에 있습니까?
Amen Jlili
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.