Java Java베이스 Java 스레드 풀에 대한 자세한 설명

Java 스레드 풀에 대한 자세한 설명

Nov 26, 2019 pm 03:05 PM
java 스레드 풀

Java 스레드 풀에 대한 자세한 설명

스레드 풀 개요

1. 스레드 풀은 스레드를 관리하는 풀로, 스레드 생성 및 소멸로 인한 리소스 소모를 줄일 수 있습니다

스레드는 실제로 개체를 생성하는 객체이기 때문입니다. 클래스 로딩 과정에서 객체를 파괴하고 GC 가비지 수집 과정을 거치는 것은 모두 리소스 오버헤드를 필요로 합니다.

2. 스레드 풀에서 스레드를 가져오는 것에 비해 응답 속도가 향상됩니다.

3. 스레드를 모두 사용하면 다시 풀에 넣습니다. , 재사용 효과 달성

( 추천 영상 : java 영상 튜토리얼)

스레드 풀 실행

비유

코어 스레드를 회사 정규 직원과 비교

비코어 스레드를 비교 아웃소싱된 직원

블로킹 큐는 수요 풀과 비교됩니다

Submit 작업은 요청하는 것과 같습니다.

Java 스레드 풀에 대한 자세한 설명

정식 실행

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime,TimeUnit unit,
   BlockingQueue<Runnable> workQueue,
   ThreadFactory threadFactory,
   RejectedExecutionHandler handler)
로그인 후 복사
corePoolSize     核心线程数
maximumPoolSize  线程池最大线程数
keepAliveTime    空闲线程存活时间
TimeUnit         线程空闲存活时间单位
workQueue        存放任务的阻塞队列
threadFactory    线程工厂
handler          饱和策略
로그인 후 복사

● 스레드 풀에 남아 있는 코어 스레드 수가 다음과 같을 때 작업을 제출합니다. corePoolSize 스레드 수보다 적은 경우 스레드 풀은 제출된 작업을 처리하기 위해 코어 스레드를 생성합니다.

● 스레드 풀의 코어 스레드 수가 가득 찬 경우, 즉 스레드 수가 corePoolSize와 동일하면 새로 제출된 작업이 작업 대기열 workQueue에 들어가 실행을 위해 대기열에 추가됩니다.

● 스레드 풀에 남아 있는 스레드 수가 corePoolSize와 같고, 작업 큐 workQueue도 가득 찼을 때 스레드 수가 maximumPoolSize에 도달했는지, 즉 최대 스레드 수가 가득 찼는지 확인합니다. , 제출 작업을 실행하기 위한 비핵심 스레드를 생성합니다.

● 현재 스레드 수가 maximumPoolSize에 도달하고 새 작업이 오면 거부 정책이 직접 사용됩니다.

여러 가지 포화 전략

AbortPolicy         抛出一个异常,默认的
DiscardPolicy       直接丢弃任务
DiscardOldestPolicy 丢弃队列里最老的任务,将当前这个任务继续提交给线程池
CallerRunsPolicy    交给线程池调用所在的线程进行处理
로그인 후 복사

스레드 풀 예외 처리

작업을 처리하기 위해 스레드 풀이 스레드를 호출할 때 발생하는 예외가 스레드 풀에 의해 포착될 수 있으므로 작업 실행이 인식되지 않을 수 있습니다. 따라서 스레드 풀 예외를 고려해야 합니다.

방법 1:

@Test
public void test1() throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(5);
    for (int i = 0; i < 5; i++) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("name: " + Thread.currentThread().getName());
                    Object a = null;
                    System.out.println(a.hashCode());
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        });
    }
}
로그인 후 복사

방법 2:

@Test
public void test2() throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(5);
    for (int i = 0; i < 20; i++) {
        Future<?> future = executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("name: " + Thread.currentThread().getName());
                Object a = null;
                System.out.println(a.hashCode());
            }
        });
        try {
            future.get();
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
로그인 후 복사

스레드 풀의 작업 대기열

● ArrayBlockingQueue

● LinkedBlockingQueue

● 동기 대기열

● DelayQueue

●P riorityBlockingQueue

==ArrayBlockingQueue==

● 특정 용량의 배열 초기화

● 재진입 잠금 사용, 기본적으로 불공정 잠금 사용, 대기열 추가 및 대기열 제거가 동일한 잠금 공유, 상호 배제

● 제한된 설계, 용량이 가득 차면 요소를 삭제할 수 없음 요소가 있을 때까지 추가됨

● 사용 시 연속 메모리를 엽니다. 초기화 용량이 너무 크면 리소스 낭비가 발생하기 쉽습니다. 초기 용량이 너무 작으면 추가에 실패하기 쉽습니다.

== LinkedBlockingQueue==

● 연결된 목록 데이터 구조 사용

● 비연속 메모리 공간

● 두 개의 재진입 잠금을 사용하여 요소의 진입과 종료를 각각 제어하고 조건을 사용하여 스레드 사이에서 깨어나고 대기합니다

● 기본 구성 방식에서는 용량이 Integer.MAX_VALUE

== 동기 대기열==

● 내부 용량은 0

● 모든 삭제 작업은 삽입 작업을 기다려야 합니다

● 모든 삽입 작업은 삭제 작업을 기다려야 합니다

● 요소는 삽입 스레드와 제거 스레드가 있으면 삽입 스레드에서 제거 스레드로 빠르게 전달됩니다. 이 컨테이너는 채널과 동일하며 저장되지 않습니다. 다중 작업 대기열에서는 작업을 처리하는 가장 빠른 방법입니다.

==PriorityBlockingQueue==

● 무한한 디자인, 그러나 용량은 실제로 시스템 리소스에 따라 다름

● 요소 추가, 1개보다 많으면 우선 순위 정렬 입력

==DelayQueue==

● 무한한 디자인

● 추가 (put) 없이 차단 제거

● 요소에는 만료 시간이 있습니다

● 만료된 요소만 제거됩니다

일반적으로 사용되는 스레드 풀

● newFixedThreadPool(고정된 수의 스레드 스레드 풀)

● newCachedThreadPool (스레드를 캐시할 수 있는 스레드 풀)

● newSingleThreadExecutor(단일 스레드 풀)

● newScheduledThreadPool(예약 및 주기적인 실행을 위한 스레드 풀)

==newFixedThreadPool==

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
로그인 후 복사

Features

1. 코어 스레드 수는 최대 스레드 수와 동일합니다

2. 소위 비유휴 시간이 없습니다. 즉, keepAliveTime은 0

3입니다. 차단 대기열은 무제한 대기열 LinkedBlockingQueue

작동 중입니다. 메커니즘:

Java 스레드 풀에 대한 자세한 설명● 작업 제출


● 스레드 수가 코어 스레드보다 적으면 코어 스레드를 생성하여 작업을 실행합니다.

● 스레드 수가 코어 스레드와 같은 경우 , LinkedBlockingQueue 차단 대기열에 작업을 추가하세요

● 如果线程执行完任务,去阻塞队列取任务,继续执行。

==newCachedThreadPool==

public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}
로그인 후 복사

线程池特点

● 核心线程数为0

● 最大线程数为Integer.MAX_VALUE

● 阻塞队列是SynchronousQueue

● 非核心线程空闲存活时间为60秒

Java 스레드 풀에 대한 자세한 설명

工作机制:

● 提交任务

● 因为没有核心线程,所以任务直接加到SynchronousQueue队列。

● 判断是否有空闲线程,如果有,就去取出任务执行。

● 如果没有空闲线程,就新建一个线程执行。

● 执行完任务的线程,还可以存活60秒,如果在这期间,接到任务,可以继续活下去;否则,被销毁。

使用场景

用于并发执行大量短期的小任务。

使用SynchronousQueue作为工作队列,工作队列本身并不限制待执行的任务的数量。但此时需要限定线程池的最大大小为一个合理的有限值,而不是Integer.MAX_VALUE,否则可能导致线程池中的工作者线程的数量一直增加到系统资源所无法承受为止。

如果应用程序确实需要比较大的工作队列容量,而又想避免无界工作队列可能导致的问题,不妨考虑SynchronousQueue。SynchronousQueue实现上并不使用缓存空间

==newSingleThreadExecutor==

线程池特点

● 核心线程数为1

● 最大线程数也为1

● 阻塞队列是LinkedBlockingQueue

● keepAliveTime为0

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>(),
                                threadFactory));
}
로그인 후 복사

工作机制

Java 스레드 풀에 대한 자세한 설명

● 提交任务

● 线程池是否有一条线程在,如果没有,新建线程执行任务

● 如果有,讲任务加到阻塞队列

● 当前的唯一线程,从队列取任务,执行完一个,再继续取,一个人(一条线程)夜以继日地干活。

使用场景

适用于串行执行任务的场景,一个任务一个任务的执行

==newScheduledThreadPool==

线程池特点

public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue());
}
로그인 후 복사

● 最大线程数为Integer.MAX_VALUE

● 阻塞队列是DelayedWorkQueue

● keepAliveTime为0

● scheduleAtFixedRate() :按某种速率周期执行

● scheduleWithFixedDelay():在某个延迟后执行

工作机制

● 添加一个任务

● 线程池中的线程从 DelayQueue 中取任务

● 线程从 DelayQueue 中获取 time 大于等于当前时间的task

● 执行完后修改这个 task 的 time 为下次被执行的时间

● 这个 task 放回DelayQueue队列中

scheduleWithFixedDelay

● 无论任务执行时间长短,都是当第一个任务执行完成之后,延迟指定时间再开始执行第二个任务

scheduleAtFixedRate

● 在任务执行时间小于间隔时间的情况下,程序以起始时间为准则,每隔指定时间执行一次,不受任务执行时间影响

● 当执行任务时间大于间隔时间,此方法不会重新开启一个新的任务进行执行,而是等待原有任务执行完成,马上开启下一个任务进行执行。此时,执行间隔时间已经被打乱

本文来自php中文网,java教程栏目,欢迎学习!

위 내용은 Java 스레드 풀에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

자바의 완전수 자바의 완전수 Aug 30, 2024 pm 04:28 PM

Java의 완전수 가이드. 여기서는 정의, Java에서 완전 숫자를 확인하는 방법, 코드 구현 예제에 대해 논의합니다.

Java의 난수 생성기 Java의 난수 생성기 Aug 30, 2024 pm 04:27 PM

Java의 난수 생성기 안내. 여기서는 예제를 통해 Java의 함수와 예제를 통해 두 가지 다른 생성기에 대해 설명합니다.

자바의 웨카 자바의 웨카 Aug 30, 2024 pm 04:28 PM

Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

Java의 스미스 번호 Java의 스미스 번호 Aug 30, 2024 pm 04:28 PM

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

Java Spring 인터뷰 질문 Java Spring 인터뷰 질문 Aug 30, 2024 pm 04:29 PM

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Feb 07, 2025 pm 12:09 PM

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

Java의 날짜까지의 타임스탬프 Java의 날짜까지의 타임스탬프 Aug 30, 2024 pm 04:28 PM

Java의 TimeStamp to Date 안내. 여기서는 소개와 예제와 함께 Java에서 타임스탬프를 날짜로 변환하는 방법에 대해서도 설명합니다.

캡슐의 양을 찾기위한 Java 프로그램 캡슐의 양을 찾기위한 Java 프로그램 Feb 07, 2025 am 11:37 AM

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

See all articles