Thread start ()와 Runnable run ()의 차이점은 무엇입니까?


224

이 두 개의 Runnable이 있다고 가정 해보십시오.

class R1 implements Runnable {
    public void run() {  }
    
}

class R2 implements Runnable {
    public void run() {  }
    
}

그렇다면 이것의 차이점은 무엇입니까?

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();

    r1.run();
    r2.run();
}

이:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);

    t1.start();
    t2.start();
}

답변:


309

첫 번째 예 : 여러 스레드가 없습니다. 둘 다 단일 (기존) 스레드에서 실행됩니다. 스레드 생성이 없습니다.

R1 r1 = new R1();
R2 r2 = new R2();

r1그리고 r2도구 용 클래스의 두 상이한 개체 Runnable인터페이스 따라서 구현 run()방법. 호출 r1.run()하면 현재 스레드에서 실행 중입니다.

두 번째 예 : 두 개의 별도 스레드.

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);

t1그리고 t2클래스의 객체입니다 Thread. 를 호출 t1.start()하면 새 스레드가 시작되고 내부적으로 해당 run()메소드를 호출하여 r1해당 새 스레드 내에서 스레드를 실행합니다.


5
나는 우리가 Thread # start ()를 호출하기 전에 os 스레드와 관련하여 아무것도 발생하지 않는다고 생각합니다. 그것은 단지 자바 객체입니다.
Jaskey

4
설명서에 따르면 맞습니다. 설명서에 맞는 스레드 객체 초기화 코드를 확인하십시오. 또한 소스 코드에서는 start()natvie 메소드를 호출하는이며, os 스레드 관련 작업을 수행해야합니다.
Bhesh Gurung

3
스레드 생성자 문서는 여기에 있습니다 . 스레드 객체 초기화 소스는 여기에 있습니다 . start()메소드 소스는 여기에 있습니다 .
Bhesh Gurung

92

방금 run()직접 호출 하면 다른 메소드 호출과 마찬가지로 호출 스레드에서 실행됩니다. Thread.start()runnable의 run메소드가 병렬로 실행 되도록 실제로 새 스레드를 작성하는 데 필요합니다 .


2
핫스팟 JVM에는 Java 스레드와 기본 스레드간에 직접 매핑이 있습니다. Thread.start()호출하면 스레드 상태가 상태에서 실행 가능 상태 로 이동 합니다. Runnable은 스레드가 실행 중임을 의미하지 않습니다. 원시 스레드가 초기화되면 원시 스레드는 run()Java 스레드에서 메소드를 호출하여 스레드 상태를 Runnable 에서 Running으로 변경 합니다. 스레드가 종료되면 기본 및 Java 스레드에 대한 모든 자원이 해제됩니다.
overexchange

@overexchange 상태 변경에 대한 자료는 어디서 찾을 수 있습니까?
twlkyao

73

차이점은 메소드 Thread.start()를 호출하는 스레드 를 시작하는 run()반면 현재 스레드 Runnable.run()에서 run()메소드를 호출하는 것입니다.


35

차이는 프로그램이 호출 할 때이다 start()방법을하는 새로운 스레드가 생성되고 코드 내부가 run()실행되지 않은 새로운 전화 할 경우 동시에 스레드 run()방법을 직접 새로운 스레드가 생성되고 코드 내부를 run()직접 현재의 thread로 실행됩니다.

Java 스레드 와의 또 다른 차이점 은 두 번 호출 할 수 없다는 것 입니다. 일단 시작되면 두 번째 호출은 Java에서 발생하지만 메소드는 일반적인 메소드 이므로 여러 번 호출 할 수 있습니다 .start()run()start()start()IllegalStateExceptionrun()


21

실제로 Thread.start()새 스레드를 만들고 자체 실행 시나리오가 있습니다.

Thread.start()run()메소드를 비동기식으로 호출하여 새 스레드의 상태를 Runnable로 변경합니다.

그러나 Thread.run()새로운 스레드를 만들지 않습니다. 대신 현재 실행중인 스레드에서 run 메소드를 동 기적으로 실행합니다.

사용중인 경우 Thread.run()멀티 스레딩 기능을 전혀 사용하지 않습니다.


8

invoke run()는 다른 메소드 호출과 마찬가지로 호출 스레드에서 실행됩니다. 반면 Thread.start()새로운 스레드를 만듭니다. 호출 run()은 프로그래밍 방식의 버그입니다.


7

run()main 메소드에서 수행하는 경우 main 메소드의 스레드는 run실행해야하는 스레드 대신 메소드를 호출합니다 .

start()메소드는 새 스레드를 작성하고 run()메소드를 수행해야합니다.


'주요 방법'은 그것과 관련이 없습니다.
Lorne의 후작

3
필자가 쓴 @EJP main는 호출 방법을 의미했습니다. 그의 대답은 아주 좋습니다. +1 ;-)
dom_beau

1
@dom_beau 그게 그가 말한 의미라면 말이다. 그가 말한 것은 틀렸다. 이 답변에 대해 '아주 좋은'것은 없습니다. 혼란스러운 혼란 일뿐입니다.
Lorne의 후작

5

t.start() 새 스레드를 원할 때 라이브러리가 코드를 호출하도록 제공하는 방법입니다.

r.run()그 방법 제공 라이브러리 호출 새로운 스레드.


이러한 답변의 대부분은 지금까지 자바 언어에 관한 한, 사이에 많은 차이가 있습니다, 그입니다 큰 그림을 놓치지 t.start()r.run()다른 두 가지 방법 사이가 이상합니다.

둘 다 단지 방법입니다. 둘 다 호출 한 스레드에서 실행 됩니다 . 둘 다 자신이 코딩 한 모든 작업을 수행 한 다음 여전히 동일한 스레드에서 호출자에게 반환합니다.

가장 큰 차이점은 대부분의 코드 t.start()기본 코드이고 대부분의 경우 코드 r.run()는 순수 Java라는 것입니다. 그러나 그것은 큰 차이가 아닙니다. 코드는 코드입니다. 네이티브 코드는 찾기가 어렵고 찾을 때 이해하기가 어렵지만 컴퓨터에 수행 할 작업을 알려주는 코드 일뿐입니다.

그래서 무엇을 t.start()합니까?

새 원시 스레드를 작성하고 해당 스레드가를 호출하도록 정렬 t.run()한 다음 OS에 새 스레드를 실행하도록 지시합니다. 그런 다음 돌아옵니다.

그리고 무엇을 r.run()합니까?

재미있는 것은,이 질문을하는 사람이 그것을 쓴 사람입니다 . r.run()어떤 않습니다 당신이 (즉, 쓴 개발자가) 그것을 할 수 있도록 설계.


4

Thread.start()코드는 스레드를 스케줄러에 등록하고 스케줄러는 run()메소드를 호출합니다 . 또한 Thread클래스 Runnable는 인터페이스입니다.


3

회원들이 만든 요점은 괜찮아서 무언가를 추가하고 싶습니다. 문제는 JAVA가 다중 상속을 지원하지 않는다는 것입니다. 그러나 클래스 B를 다른 클래스 A에서 파생 시키려면 어떻게합니까? 그러나 한 클래스에서만 파생 할 수 있습니다. 문제는 이제 클래스 A와 스레드에서 "파생"하는 방법입니다. 따라서 Runnable Interface를 사용할 수 있습니다.

public class ThreadTest{
   public void method(){
      Thread myThread = new Thread(new B());
      myThread.start;
   }
}

public class B extends A implements Runnable{...

잘 실행의 설명 ()의 Runnable에 대한 예를의 도움으로 방법 - 인터페이스 및 스레드 - 클래스
핑키 Walve

1

run()메소드 를 직접 호출 하면 run()메소드가 호출자 스레드의 일부로 실행 되므로 멀티 스레딩 기능을 사용하지 않습니다 .

start()스레드에서 메소드 를 호출 하면 Java Virtual Machine은 run () 메소드를 호출하고 두 개의 스레드 (현재 스레드 ( main()예제) 및 기타 스레드 (예제에서 실행 가능))가 동시에 실행됩니다 r1.

Thread 클래스start() 에서 메소드의 소스 코드를 살펴보십시오.

 /**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.
     * <p>
     * The result is that two threads are running concurrently: the
     * current thread (which returns from the call to the
     * <code>start</code> method) and the other thread (which executes its
     * <code>run</code> method).
     * <p>
     * It is never legal to start a thread more than once.
     * In particular, a thread may not be restarted once it has completed
     * execution.
     *
     * @exception  IllegalThreadStateException  if the thread was already
     *               started.
     * @see        #run()
     * @see        #stop()
     */
    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();

위의 코드에서는 run()메소드 호출을 볼 수 없습니다 .

private native void start0()run()메소드 호출을 담당합니다 . JVM은이 기본 메소드를 실행합니다.


0

첫 번째 경우 run()에는 r1and r2객체 의 메소드를 호출하는 것입니다 .

두 번째 경우에는 실제로 2 개의 새로운 스레드를 생성합니다!

start()run()어느 시점에서 전화 합니다!


7
실제로 start ()는 run ()을 호출하지 않습니다. 그렇게하면 run () 메서드는 start ()를 호출 한 동일한 스레드에서 실행됩니다. start ()는 run () 메소드를 호출하는 스레드를 작성합니다.
Bruno Reis

0

run method : -Runnable 인터페이스에서 원래 생성되어 Thread 클래스뿐만 아니라 Thread 서브 클래스 (소스 코드에서 Runnable을 구현함에 따라) 및 Runnable 인터페이스의 다른 구현 클래스에서 재정의되는 추상 메소드입니다. -스레드 (실행 가능한 개체)를 작업을로드하는 데 사용되므로 작업을 작성하기 위해 스레드를 재정의합니다.

시작 방법 : -Thread 클래스에서 정의됩니다. Thread 객체 1 에서 start 메소드를 호출하면 start0 ()이라는 내부적으로 네이티브 (비 Java) 메소드를 호출합니다. 방법.

start0 (); 메소드 : 준비 / 실행 가능 상태의 스레드가있는 시점에서 처리량이 적습니다 (스레드의 스택 작성 및 프로세서 대기열에 스레드 할당).

2- 스레드 스케줄러가 스레드가 프로세서 코어에 들어가기로 결정한 시점 (스레드 우선 순위 및 OS 스케줄링 알고리즘)에 따라 Runnable 오브젝트 (현재 Runnable 스레드 오브젝트 또는 전달 된 Runnable 오브젝트에 관계없이)에서 run 메소드가 호출됩니다. 스레드 생성자에게) 여기에서 스레드는 실행 중 상태가되고 작업 실행을 시작합니다 (실행 방법).


-2

Thread 클래스의 별도 start () 및 run () 메소드는 스레드 프로그램을 작성하는 두 가지 방법을 제공합니다. start () 메소드는 새 스레드의 실행을 시작하고 run () 메소드를 호출합니다. start () 메소드는 즉시 리턴하고 run () 메소드가 리턴 될 때까지 새 스레드는 정상적으로 계속됩니다.

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

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


2
`run () '을 호출하는 것은 스레드 프로그램을 만드는 방법이 아닙니다. 한 가지 방법이 있습니다.
Lorne의 후작

-2

Thread 확장 클래스의 Start () 메소드 호출 실행 재정의 메소드 및 Runnable은 인터페이스를 구현합니다.

그러나 run ()을 호출하면 run 메소드를 검색하지만 Runnable 인터페이스를 구현하는 클래스 인 경우 runnable의 run () override 메소드를 호출합니다.

전의.:

`

public class Main1
{
A a=new A();
B b=new B();
a.run();//This call run() of Thread because run() of Thread only call when class 
        //implements with Runnable not when class extends Thread.
b.run();//This not run anything because no run method found in class B but it 
        //didn't show any error.

a.start();//this call run() of Thread
b.start();//this call run() of Thread
}

class A implements Runnable{
@Override
    public void run() {
            System.out.println("A ");
    }
}

class B extends Thread {

    @Override
    public void run() {
            System.out.println("B ");
    }
}

`

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