[java] Thread가 추상 클래스가 아니고 start ()가 final이 아닌 이유는 무엇입니까?

Thread클래스가 추상 클래스가 아닌 일반 클래스로 구현 된 이유는run() 메서드가 추상 인

문제가 생길 수 있습니까? 아니면 이런 식으로 사용합니까?

또한이 Thread.start()메서드는 다른 클래스에서 기능을 구현할 수없는 매우 구체적인 메서드 여야합니다 (내가 틀리지 않은 경우). 따라서 final키워드가 다른 방법보다 더 적합 할 것이라고 생각합니다 .

하지만이 방법을 재정의하고 원하는대로 사용할 수 있습니다.

public class Test extends Thread {
    public static void main (String... args) {
        Thread test = new Test();
        test.start();
    }

    @Override
    public void run() {
        System.out.println("New thread started...");
    }

    @Override
    public void start() {
        System.out.println("Did anyone tell you I will spawn a new thread??");
    }
}

분명히 인쇄 만했는데

누군가 내가 새 스레드를 생성 할 것이라고 말했습니까 ??

엔지니어가 당신을 대체하는 것을 혼란스럽게하는 것 외에 재정의에 어떤 용도가 있습니까?

그렇지 않다면 왜 메소드가 Thread 클래스에서 final로 선언되지 않았습니까?



답변

Thread 클래스가 run () 메서드가 추상 인 추상 클래스가 아닌 일반 클래스로 구현 된 이유는 무엇입니까?

이 질문은 실제로 상속보다 구성을 선호해야한다는 사실로 귀결됩니다.

경우 Thread클래스가 선언 된 abstract언어는 프로그래머가를 만드는 데 사용할 수있는 그것에서 확장 된 다른 클래스를 제공 할 것입니다 Thread. 이 클래스의 것을 왜 귀하의 질문은 다음에 대한 것 extends부터가 Thread아니다 abstract. 언어가 extends에서 온 다른 클래스를 제공하지 않으면 Thread프로그래머는 메서드 extend에서 시작 Thread하고 재정의하는 자체 클래스를 만들어야합니다 run().

그렇지 않다면 왜 메소드가 Thread 클래스에서 final로 선언되지 않았습니까 ??

내가 줄 수있는 유일한 설명은 언어 개발자가 start클래스가 JDK에 도입되었을 때 재정의하는 몇 가지 사용 사례를 보았다 는 것입니다. 내가 사용한 Java의 첫 번째 버전은 1.5였으며 개인적으로을 재정의해야하는 사용 사례를 발견하지 못했습니다 start. JB Nizet이 그의 답변에서 말했듯이

Java가 오늘 처음부터 다시 디자인 되었다면 디자인이 다를 가능성이 높습니다.


답변

물론 발로 자신을 쏠 수도 있지만 그렇다고해서 반드시해야하는 것은 아닙니다.

Thread 클래스가 run () 메서드가 추상 인 추상 클래스가 아닌 일반 클래스로 구현 된 이유는 무엇입니까?

시작 스레드를 만드는 데 권장되는 방법은 Thread를 하위 클래스로 만드는 것이 아니기 때문입니다. 권장되는 방법은를 정의 Runnable하고 Thread 생성자에 인수로 전달하는 것입니다.

Runnable r = new Runnable() {
    @Override
    public void run() {
        ...
    }
};
Thread t = new Thread(r);
t.start();

따라서 최종 키워드가 다른 방법보다 더 적합 할 것이라고 생각합니다.

예, 아니오. start () 구현을 자체 구현으로 대체 할 수는 없지만 원하는 경우 start ()에서 추가 작업을 수행 할 수 있습니다 .

@Override
public void start() {
    System.out.println("Did anyone tell you I will spawn a new thread??");
    super.start();
}

즉, Java가 오늘 처음부터 다시 디자인 되었다면 디자인이 다를 가능성이 높습니다. 이 클래스는 Java 1.0에서 시작되었으며 여전히 이전 버전과 호환됩니다.


답변

Thread.start()그렇지 final않습니까?

당신이 있습니까 장해야 당신이 그것을 무시하고 싶지는 않을 것이다?

Class MyThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        return new Thread(r) {
            @Override
            public void start() {
                LOGGER.info("Starting thread " + this);
                super.start();
            }
        };
    }
}


답변

답변에 대한 몇 가지 calirifcations가 게시되어야한다고 생각합니다.

“당신은 그것을 무시하고 싶지 않을 것이 확실합니까?”

아니 ! 내가 않을 것. “정말로이 변수를 private으로 선언 하시겠습니까?”라고 말하는 것과 같습니다. 다른 개발자가 내 디자인 로직을 엉망으로 만들지 않을까 걱정하지 않고 내가 사용하는 변수를 공개로 선언 할 수 있다면 코딩이 수월 할 것입니다. 범위, 추상화, 다형성, 오류 처리 등의 OOPS 개념의 가장 중요한 목적 중 하나는 다른 개발자에게 코드이면의 디자인과 의도를 전달하는 것입니다. 질문에서 지적했듯이 시작 메서드를 재정의 할 때 아무도 강제하지 않습니다. super.start ()를 사용합니다. @Codebender는 super.start ()를 사용하지 않고 스레드에 대한 시작 메서드를 작성했으며 컴파일러는 불평하지 않았습니다. 그래서 그는 스레딩의 전체 메커니즘을 자유롭게 깰 수 있으며 컴파일러는 그냥 통과시키는 것으로 가정합니까? 스레드의 시작 메서드는 run 메서드가 적절한 시간에 호출되고 실행되도록합니다! 스레딩이라는 개념에 매우 중요합니다. 여기에서 뭔가를 놓친 경우 수정되어 기쁠 것입니다. 2.

스레드를 시작하는 데 권장되는 방법은 Thread를 하위 클래스로 만드는 것이 아니기 때문입니다.

좋아, 만약 codebender가 디자인에 의해 허용된다면, Thread를 sublass하고 시작 방법을 엉망으로 만들 수 있습니다. 그 논리에 의해, 그것은 디자인 자체가 발을 쏘는 것입니다. (내가 완전히 동의하는) 다른 진술에 따르면 Runnable이 권장되는 방법입니다. 그렇다면 왜 Thread 클래스가 제한없이 스레드를 인스턴스화하도록 허용합니까? 다음은 다음과 같습니다.

start () 구현을 자신의 구현으로 바꿀 수는 없습니다.

그것은 실제로 시작 방법이 최종적이어야한다는 코드 벤더의 주장을 뒷받침합니다 .. ^

유효한 한 가지 요점은 이미 부수적으로 언급되었지만 이 질문에 대한 실제 답변입니다.

“하위 호환성”.

사실 Java 동시성 모델에 대한 많은 주요 추가 및 설명을 통합 한 JDK 5.0까지 개선이 진행되었습니다. 우리는 이전 버전과의 호환성이 항상 지원되기를 원하며, 이것이 오늘날 Runnable 인터페이스가 권장되는 방법 임에도 불구하고 Thread 클래스가 이전과 똑같은 이유입니다.

다시 말하지만, 내가 뭔가를 놓친 경우 수정되는 것보다 기쁠 것입니다.


답변