Java 5에서 시작하여 Java는 자체 스레드 풀을 제공합니다. 스레드 풀은 스레드 컨테이너로 한 번에 정격 스레드 수만 실행합니다. java.util.concurrent.threadpoolexecutor는 그러한 스레드 풀입니다. 매우 유연하지만 사용하기가 복잡 하므로이 기사에서 소개합니다.
첫 번째는 생성자입니다. 가장 간단한 생성자를 예로 들어보십시오.
Public ThreadPooleExecutor (int corepoolsize, int maximumpoolsize, 긴 keepalivetime, TimeUnit 장치, blockingqueue <Runnable> Workqueue)
꽤 복잡해 보입니다. 여기에 소개하겠습니다.
CorePoolSize는 예약 된 스레드 풀 크기를 나타냅니다.
MaxImumpOlsize는 스레드 풀의 최대 크기를 나타냅니다.
KeepAlivetime은 유휴 스레드가 끝나는 시간 초과 시간을 나타냅니다.
단위는 Keepalivetime의 단위를 나타내는 열거입니다.
Workqueue는 작업을 저장하기위한 대기열을 나타냅니다.
스레드 풀의 작업 프로세스에서 이러한 매개 변수의 중요성을 이해할 수 있습니다. 스레드 풀의 작업 과정은 다음과 같습니다.
1. 스레드 풀이 처음 만들어 졌을 때 내부에 실이 없었습니다. 작업 대기열은 매개 변수로 전달됩니다. 그러나 큐에 작업이 있더라도 스레드 풀이 즉시 실행되지 않습니다.
2. execute () 메소드를 호출하여 작업을 추가 할 때 스레드 풀이 다음과 같은 판단을 내립니다.
a. 실행중인 스레드 수가 CorePoolSize보다 적은 경우이 작업을 즉시 실행할 스레드를 작성하십시오.
b. 실행중인 스레드 수가 CorePoolSize보다 크거나 동일하다면이 작업을 대기열에 넣으십시오.
c. 현재 대기열이 가득 차 있고 실행 된 스레드 수가 MaximumpOollsize보다 낮 으면이 작업을 실행하려면 스레드를 만들어야합니다.
d. 대기열이 가득 차 있고 실행 된 스레드 수가 MaximumpOollsize보다 크거나 같으면 스레드 풀에 발신자에게 "더 이상 작업을 수락 할 수 없다"는 예외가 발생합니다.
3. 스레드가 작업을 완료하면 큐에서 작업을 수행하는 데 작업이 필요합니다.
4. 스레드에 할 일이없고 일정 시간이 걸리면 (recalivetime), 스레드 풀은 현재 실행중인 스레드 수가 CorePoolSize보다 크면 스레드가 중지된다고 판단합니다. 따라서 스레드 풀의 모든 작업이 완료되면 결국 CorePoolSize 크기로 줄어 듭니다.
이 프로세스는 작업에 먼저 참여하면 먼저 작업을 실행할 필요가 없음을 보여줍니다. 큐 크기가 10이고 CorePoolsize가 3이고 MaximumpOollsize가 6이라고 가정하면 20 개의 작업이 추가되면 실행 순서가 다음과 같습니다. 첫째, 작업 1, 2, 3이 실행되고 4 ~ 13이 배치됩니다. 대기열에서. 이때, 대기열이 가득 차고, 작업 14, 15, 16은 즉시 실행되며, 작업 17 ~ 20은 예외를 던집니다. 최종 순서는 1, 2, 3, 14, 15, 16, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13입니다. 다음은 스레드 풀 사용의 예입니다.
public static void main (string [] args) {blockingqueue <Runnable> queue = threadpoolexecutor executor (3, 6, 1, timeUnit.days, queue); 0; i <20; i ++) {executor.execute () {public void run () {thread.sleep (1000);} catch (e.printstacktr ace ();} 시스템. println.
이 예제에 대한 설명은 다음과 같습니다.
1. Blockingqueue는 단지 인터페이스 일뿐입니다. LinkedBlockingqueue를 사용하는 장점은 크기 제한이 없다는 것입니다. 이런 식으로 큐가 가득 차 있지 않기 때문에 Execute ()는 예외를 던지지 않으며 스레드 풀에서 실행되는 스레드 수는 CorePoolSize를 초과하지 않으므로 requalivetime 매개 변수는 의미가 없습니다.
2. shutdown () 메소드가 차단되지 않습니다. shutdown () 메소드를 호출 한 후 메인 스레드가 즉시 종료되고 스레드 풀이 중지되기 전에 모든 작업이 실행될 때까지 계속 실행됩니다. shutdown () 메소드가 호출되지 않으면 스레드 풀은 언제든지 새 작업을 추가 할 수 있도록 유지됩니다.
이 시점 에서이 스레드 풀의 작은 부분 만 소개했습니다. ThreadPooleExecutor는 매우 확장 가능하지만 확장의 전제는 작동 방식에 익숙해야합니다. 다음 기사에서는 ThreadPooleExecutor 클래스를 확장하는 방법을 설명합니다.
ava.util.concurrent.threadpoolexecutor 클래스는 풍부한 확장 성을 제공합니다. 서브 클래스를 만들어 동작을 사용자 정의 할 수 있습니다. 예를 들어, 각 작업이 끝나면 메시지를 인쇄하고 싶지만 작업 객체를 수정할 수는 없으며 다음을 작성할 수 있습니다.
ThreadPoolExecutor Executor = New ThreadPoolexecutor (size, maxsize, 1, timeUnit.days, queue) {@override protected void afterExecute (runnable r, t hrowable t) {System.out.println ( "작업 완료");
후보 꺼짐 메소드 외에도 ThreadPooleExecutor 클래스는 이전에 execute () 및 종료 () 메소드가 있으며 재정의 할 수있는 메소드가 있으며 작업이 실행되기 전에 실행되고 전체 스레드 풀이 중지 된 후에도 실행됩니다.
작업이 실행되기 전후 작업을 추가하는 것 외에도 ThreadPooleExecutor를 사용하면 작업이 실패한 후 실행 정책을 사용자 정의 할 수 있습니다. 스레드 풀의 setReceDexecutionHandler () 메소드를 호출하고 기존 정책을 사용자 정의 RejectedExecutionHandler 개체로 바꿀 수 있습니다. ThreadPooleExecutor는 4 개의 기존 정책, 즉 다음을 제공합니다.
ThreadPoolexecutor.AbortPolicy : 작업이 거부되고 예외가 발생했음을 나타냅니다.
ThreadPoolexecutor.DiscArdPolicy : 작업을 거부하지만 아무런 조치도하지 않는 것을 의미합니다.
ThreadPoolExecutor.callerRunspolicy : 작업이 거부되고 작업이 발신자의 스레드에서 직접 실행되었음을 나타냅니다.
ThreadPoolExecutor.discardOldestPolicy : 작업 대기열의 첫 번째 작업이 먼저 폐기 된 다음 작업이 큐에 추가되었음을 의미합니다.
예는 다음과 같습니다.
ThreadPooleExecutor Executor = New ThreadPoolexecutor (크기, 최대 크기, 1, TimeUnit.days, 큐);
Executor.SetRecedExecutionHandler (New ThreadPoolexecutor.discardPolicy ());
또한 거부 executionHandler 인터페이스를 구현하여 자체 정책을 작성할 수도 있습니다. 예는 다음과 같습니다.
ThreadPoolExecutor Executor = New ThreadPoolexecutor (3, 6, 1, TimeUnit.seconds, Queue, New RejectedExecutionHandler () {public void RejectedExecuti on (Runnable R, ThreadPooleExecutor) {System.out.out.out.out.format ( "task %d Deject ("task %d dejected . ", R.HashCode ());}});