나는 항상 스레드를 만드는 것이 비싸다는 것을 읽었습니다.
또한 스레드를 다시 실행할 수 없다는 것도 알고 있습니다.자바 스레드 재사용
나는 Executors
클래스의 문서에 참조 :
는 필요에 따라 새 스레드를 작성하는 thread 풀을 작성하지만, 사용할 수있는 경우에는 이전에 구축 된 thread를 재사용합니다.
'재사용'이라는 단어를 유의하십시오.
스레드 풀의 '재사용'스레드는 어떻게됩니까?
나는 항상 스레드를 만드는 것이 비싸다는 것을 읽었습니다.
또한 스레드를 다시 실행할 수 없다는 것도 알고 있습니다.자바 스레드 재사용
나는 Executors
클래스의 문서에 참조 :
는 필요에 따라 새 스레드를 작성하는 thread 풀을 작성하지만, 사용할 수있는 경우에는 이전에 구축 된 thread를 재사용합니다.
'재사용'이라는 단어를 유의하십시오.
스레드 풀의 '재사용'스레드는 어떻게됩니까?
나는 내가 지금 여기 내 더 이상 대답의 당신을 confuzzabling 무슨 이해 생각
스레드 풀의 '재사용'스레드는 어떻게됩니까?
어떤 일이 일어나고은 단일 스레드는 일반적으로 Runnable
로 전달 여러 가지 작업을 (처리하는 데 사용하지만, 이것이 당신의 '집행자'프레임 워크에 의존 할 수 있다는 것입니다 : 기본 집행이 Runnable
을 수락,하지만 당신은 당신의 자신의 "유언 집행을 쓸 수 "/ 스레드 풀은 Runnable
[예 : CancellableRunnable
]보다 복잡한 것을 받아들입니다.
구현시 기본값으로 ExecutorService
구현에서 스레드가 여전히 사용 중 종료되는 경우 자동으로 새 스레드로 대체되지만 이는 다시 '재사용'이 아닙니다. 이 경우에는 "재사용"이 없습니다.
그래서 당신은 당신이 실행기에 원하는만큼 Runnable
를 전달할 수 있습니다 각 Runnable
의 run()
방법은 한 번만 호출해야한다 두 번 자바 스레드에 을 start()
를 호출 할 수는 없지만 사실이다.
당신은 run()
6 회가 (실제적으로 정확히 6 Runnable
Thread
마다 실행됩니다하지만 그 세부 사항이다가 보장 할 것), 예를 들어, 각 작업자 스레드가 호출 할 수있다 (30) Runnable
자바 Thread
5 및 전달할 수 있습니다.
이 예제에서 start()
은 6 번 호출되었을 것입니다.
Thread.start()
자바 독에서 : Runnable
가 대기열에서 제거해야한다
* Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread.
하지만 각 스레드의 run()
방법 안에이 6 start()
각 Thread
의 정확히 한 번만run()
메서드를 호출합니다 각각 각 Runnable
의 run()
방법이 호출 될 예정입니다. 따라서 각 스레드는 여러 개의 Runnable
을 처리 할 수 있습니다. 그것이 "스레드 재사용"에 의해 참조됩니다. 자신의 스레드 풀을 할
한 가지 방법은보다 Runnable를 대기열과는 다음 Runnable
(또는 블록) 대기열에서 제외하는 Runnable
의 run()
방법을 처리 완료 된 후에는, 스레드의 각이있는에 차단 큐를 사용하는 것입니다 run()
방법을 실행 한 다음 헹구고 반복하십시오.
나는 혼란의 일부를 추측 기본 스레드 풀 도이 Runnable
을하는 동안 Thread
가 실행 가능한의 run()
메소드가 호출되는 Runnable
및 start()
를 호출에 걸린다는 사실에서 온다 (그리고는 약간 혼동이) .
스레드 풀은 내부 작업 큐에서 작업을 수행 할 수있는 여러 고정 작업자 스레드로 구성됩니다. 따라서 하나의 작업이 끝나면 스레드는 이 아니며이 아니라 다음 작업을 기다립니다. 스레드를 중단하면 자동으로 대체됩니다.
자세한 내용은 documentation을 참조하십시오.
thread
이 완료되면 다시 사용할 수 있는지 확인하십시오. isAlive()
또는 비슷한 것을 호출하여 실행되지 않는지 확인할 수 있습니다.
수정 : 누군가 thread
을 일시 중지 한 경우 다시 시작할 수 없습니다. 나는 그것이 정상적으로 끝난다면 시작할 수없는 이유는 없습니다. 하지만 의심의 여지가 있으며 은 재사용 할 수 없다고 말합니다.
@fastcodejava : 스레드가 완료되면 * start() *를 다시 호출 할 수 없으므로 * IllegalThreadStateException *이 발생합니다. – SyntaxT3rr0r
run
스레드 풀의 스레드 방법은 단일 작업 실행으로 만 구성되지 않습니다. 스레드 풀의 스레드에 대한 run
메서드는 루프를 포함합니다. 작업을 대기열에서 꺼내어 작업이 완료되면 작업을 실행하고 (완료되면 을 루프으로 되돌림) 다음 작업을 가져옵니다. run
메서드는 스레드가 더 이상 필요하지 않을 때까지 완료되지 않습니다.
편집 추가 할 :
여기가 ThreadPoolExecutor에서 Worker
내부 클래스의 run
방법이다. (분명, 또는 특별히 '재사용'에 중점을두고 그 질문을하지 않을) 용어가 작은 약간 오해의 소지가있다 :
696: /**
697: * Main run loop
698: */
699: public void run() {
700: try {
701: Runnable task = firstTask;
702: firstTask = null;
703: while (task != null || (task = getTask()) != null) {
704: runTask(task);
705: task = null; // unnecessary but can help GC
706: }
707: } finally {
708: workerDone(this);
709: }
710: }
@Mike Daniels : 정확히 말하자면, "task = null;"*을 지정하고 "* 불필요하지만 GC를 도울 수 있습니다"*라는 Sun 코드를 좋아해야합니다. 당신은 코드를 여기에 올리면 groupthinkers에 의해 당신이 얼마나 무의미한 지 알려주는 목구멍에 뛰어들 것입니다.) – SyntaxT3rr0r
@Wizard : 실제로 불필요한 것은 아닙니다 - (이상한) 작업 테스트! = 루프에 null이 있으면 동일한 작업을 계속 처리하지 못하게해야합니다. 루프가 더 통상적 인 경우에도, 오랫동안 getTask() 블록을 사용하면 작업의 GC가 동일한 시간 동안 지연 될 수 있기 때문에 nulling 작업이 좋을 것입니다. –
@ Software Monkey : 두 번째 요점에 대해 매우 통찰력이 있습니다. 'getTask'는 아마 타임 아웃을 가진 블로킹 큐에서 빠져 나옵니다. 타임 아웃의 전체 기간 동안 차단 될 수 있습니다. 작업에 많은 필드가있는 경우 (작업에 전달 된 매개 변수 용) 이전 GC가 도움이됩니다. –
스레드 풀은 자체 스레드를 생성하고 스레드에 대해 자체의 영리한 Runnables를 제공합니다. 그러한 Runnable는 결코 종료하지 않고 Callable가 그 큐에 존재할 때까지 큐 (대기())로 동기합니다. 그 일이 발생하면 (자) 통지를받습니다. Runnable는 큐로부터 Callable를 실행 해, 시나리오 전체가 다시 반복합니다.
tl; dr 스레드 풀 스레드는 기본적으로 제출 된 작업을 대기열에서 끌어내는 실행 루프입니다.스레드는 작업을 처리 할 때 실행을 멈추지 않고 다음 스레드가 대기열에 제출 될 때까지 대기합니다. 그들은 끊임없이 달리기 때문에 질문에서 묻는대로 결코 '재방송'을하지 않습니다. – Sogger