자바 ExecutorService 네 가지 스 레 드 탱크 사용 상세 설명
7948 단어 JavaExecutorService
스 레 드 탱크 를 합 리 적 으로 이용 하면 세 가지 좋 은 점 을 가 져 올 수 있다.첫째:자원 소 모 를 줄인다.만 든 스 레 드 를 반복 적 으로 이용 하여 스 레 드 생 성 과 소각 로 인 한 소 모 를 줄 입 니 다.둘째:응답 속 도 를 높 인 다.작업 이 도 착 했 을 때 작업 은 스 레 드 가 만들어 질 때 까지 기다 리 지 않 고 바로 수행 할 수 있 습 니 다.셋째,스 레 드 의 관리 성 을 향상 시킨다.스 레 드 는 희소 한 자원 이다.만약 에 무제 한 으로 만 들 면 시스템 자원 을 소모 할 뿐만 아니 라 시스템 의 안정성 도 낮 출 수 있다.스 레 드 탱크 를 사용 하면 통 일 된 분배,조정 과 감 시 를 할 수 있다.그러나 스 레 드 탱크 를 합 리 적 으로 이용 하려 면 그 원 리 를 손금 보 듯 잘 알 아야 한다.
2.스 레 드 탱크 사용
Executors 가 제공 하 는 네 가지 스 레 드 1.new CachedThreadPool 은 캐 시 스 레 드 풀 을 만 듭 니 다.스 레 드 풀 의 길이 가 처리 수 요 를 초과 하면 남 은 스 레 드 를 유연 하 게 회수 할 수 있 습 니 다.회수 할 수 없 으 면 새 스 레 드 를 만 듭 니 다.2.new Fixed ThreadPool 은 고정 라인 풀 을 만 들 고 스 레 드 의 최대 병발 수 를 제어 할 수 있 으 며 초과 한 스 레 드 는 대기 열 에서 기다 릴 수 있 습 니 다.3.new Scheduled ThreadPool 은 정기 적 이 고 주기 적 인 작업 수행 을 지원 하 는 고정 라인 풀 을 만 듭 니 다.4.new Single ThreadExecutor 는 단일 라인 화 된 스 레 드 풀 을 만 듭 니 다.유일한 작업 스 레 드 로 만 작업 을 수행 하고 모든 작업 이 지 정 된 순서(FIFO,LIFO,우선 순위)에 따라 실 행 될 수 있 도록 합 니 다.
1.new CachedThreadPool 은 캐 시 가능 한 스 레 드 풀 을 만 듭 니 다.스 레 드 풀 의 길이 가 처리 수 요 를 초과 하면 남 은 스 레 드 를 유연 하 게 회수 할 수 있 습 니 다.회수 할 수 없 으 면 새 스 레 드 를 만 듭 니 다.예 는 아래 와 같다.
ExecutorService executorService = Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
final int index = i;
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "," +index);
}
});
}
//
pool-1-thread-1,0
pool-1-thread-1,1
pool-1-thread-1,2
pool-1-thread-1,3
pool-1-thread-1,4
2.new Fixed ThreadPool 은 고정 라인 풀 을 만 들 고 스 레 드 의 최대 병발 수 를 제어 할 수 있 으 며 초과 한 스 레 드 는 대기 열 에서 기다 릴 수 있 습 니 다.예 는 아래 와 같다.
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
for(int i=0;i<5;i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + ", " + index);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
//
pool-1-thread-1,0
pool-1-thread-2,1
pool-1-thread-3,2
pool-1-thread-4,3
pool-1-thread-1,4
3.new Scheduled ThreadPool 은 정기 적 인 라인 풀 을 만 들 고 주기 와 정시 작업 예 시 는 다음 과 같 습 니 다.
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
System.out.println("before:" + System.currentTimeMillis()/1000);
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println(" 3 :" + System.currentTimeMillis()/1000);
}
}, 3, TimeUnit.SECONDS);
System.out.println("after :" +System.currentTimeMillis()/1000);
//
before:1518012703
after :1518012703
3 :1518012706
System.out.println("before:" + System.currentTimeMillis()/1000);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(" 1 ,3 :" +System.currentTimeMillis()/1000);
}
}, 1, 3, TimeUnit.SECONDS);
System.out.println("after :" +System.currentTimeMillis()/1000);
콘 솔 메시지before:1518013024
after :1518013024
1 초 지연 후 3 초 에 한 번 실행:1518013025
1 초 지연 후 3 초 에 한 번 실행:1518013028
1 초 지연 후 3 초 에 한 번 실행:1518013031
4.new Single ThreadExecutor 는 단일 라인 화 된 스 레 드 풀 을 만 들 고 작업 스 레 드 로 만 작업 을 수행 합 니 다.순 서 를 보장 합 니 다.예 를 들 어 다음 과 같 습 니 다.
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i=0;i<10;i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "," + index);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
콘 솔 정보pool-1-thread-1,0
pool-1-thread-1,1
pool-1-thread-1,2
pool-1-thread-1,3
pool-1-thread-1,4
스 레 드 풀 에 작업 을 제출 하 는 ThreadPoolExecutor 클래스 에서 execute()와 submit()의 구별 execute()방법 은 사실상 Executor 에서 설명 하 는 방법 으로 ThreadPoolExecutor 에서 구체 적 으로 실현 되 었 습 니 다.이 방법 은 ThreadPoolExecutor 의 핵심 방법 입 니 다.이 방법 을 통 해 스 레 드 풀 에 작업 을 제출 하고 스 레 드 풀 에 맡 길 수 있 습 니 다.
submit()방법 은 ExecutorService 에서 설명 하 는 방법 입 니 다.AbstractExecutorService 에서 구체 적 으로 실현 되 었 습 니 다.Thread PoolExecutor 에서 재 작성 하지 않 았 습 니 다.이 방법 도 스 레 드 탱크 에 임 무 를 제출 하 는 데 사 용 됩 니 다.그러나 execute()방법 과 달리 임 무 를 수행 한 결 과 를 되 돌려 주 고 소스 코드 를 통 해 submit()방법의 실현 을 볼 수 있 습 니 다.실제로 호출 된 execute()방법 인 것 을 발견 할 수 있 습 니 다.다만 Future 를 이용 하여 작업 수행 결 과 를 얻 었 을 뿐 입 니 다.
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
스 레 드 탱크 의 닫 기 는 스 레 드 탱크 의 shutdown 이나 shutdown Now 방법 으로 스 레 드 탱크 를 닫 을 수 있 습 니 다.그러나 이들 의 실현 원 리 는 다 릅 니 다.shutdown 의 원 리 는 스 레 드 탱크 의 상 태 를 SHUTDOWN 상태 로 설정 한 다음 에 작업 을 수행 하고 있 지 않 은 모든 스 레 드 를 중단 하 는 것 입 니 다.shutdown Now 의 원 리 는 스 레 드 탱크 의 작업 스 레 드 를 옮 겨 다 니 며 스 레 드 의 interrupt 방법 으로 스 레 드 를 중단 하 는 것 입 니 다.따라서 중단 되 는 작업 에 응답 하지 못 하면 영원히 종료 할 수 없습니다.shutdown Now 는 먼저 스 레 드 탱크 의 상 태 를 STOP 로 설정 한 다음 작업 을 수행 하거나 중단 하 는 모든 스 레 드 를 중단 하고 작업 을 기다 리 는 목록 을 되 돌려 줍 니 다.이 두 개의 닫 는 방법 중 하 나 를 호출 하면 isShutdown 방법 은 true 로 돌아 갑 니 다.모든 작업 이 닫 힌 후에 야 스 레 드 풀 이 닫 혔 음 을 표시 합 니 다.이 때 isTermined 방법 을 사용 하면 true 로 돌아 갑 니 다.스 레 드 풀 을 닫 기 위해 서 는 어떤 방법 을 사용 해 야 하 는 지 에 대해 서 는 스 레 드 풀 에 제출 된 작업 특성 에 의 해 결정 되 어야 합 니 다.보통 shutdown 을 사용 하여 스 레 드 풀 을 닫 습 니 다.작업 이 끝나 지 않 으 면 shutdown Now 를 호출 할 수 있 습 니 다.
3. 스 레 드 탱크 의 분석
프로 세 스 분석:스 레 드 탱크 의 주요 작업 절 차 는 다음 과 같다.자바 스 레 드 탱크 의 주요 작업 절차
위의 그림 에서 알 수 있 듯 이 새로운 작업 을 스 레 드 탱크 에 제출 할 때 스 레 드 탱크 의 처리 절 차 는 다음 과 같다.
4.567917.우선 스 레 드 탱크 는 기본 스 레 드 탱크 가 가득 찼 는 지 판단 합 니까?가득 차지 않 았 습 니 다.작업 스 레 드 를 만들어 서 작업 을 수행 합 니 다.가득 차 면 다음 절차 로 들어간다
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
작업 라인.스 레 드 탱크 가 스 레 드 를 만 들 때 스 레 드 를 작업 스 레 드 Worker 로 밀봉 합 니 다.Worker 는 작업 을 수행 한 후에 작업 대기 열 에 있 는 작업 을 무한 순환 으로 가 져 옵 니 다.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.