>Java >java지도 시간 >Java 스레드 풀의 원리, 사용법 및 성능 최적화 방법은 무엇입니까?

Java 스레드 풀의 원리, 사용법 및 성능 최적화 방법은 무엇입니까?

PHPz
PHPz앞으로
2023-05-09 19:10:061222검색

1. 스레드와 스레드 풀이란 무엇입니까?

스레드는 운영 체제의 타이밍 스케줄링의 기본 단위입니다.

스레드 풀은 스레드만 포함할 수 있는 컨테이너인 스레드가 있는 풀로 이해될 수 있습니다. 이 용기는 크기가 다양하며 7~8개 또는 3~4개를 담을 수 있습니다. 컨테이너를 채울 수도 있지만 12와 같은 최대값이 있습니다. 예를 들어 여기의 스레드 풀은 일반적으로 5개의 스레드를 포함하며 최대 12개의 스레드를 포함할 수 있습니다. 이때 스레드 풀을 사용해야 할 사람이 5명이 있어서 스레드 5개를 빼앗았는데 나중에 두 사람이 오면 사용할 스레드가 없어 그 5명이 사용이 끝날 때까지 기다려야 했습니다. 그것. 하지만 내 풀은 12개를 수용할 수 있습니다. 스레드가 5개밖에 없다면 어떻게 해야 합니까? 확실히 스레드를 몇 개 더 설치해야 합니다. 그렇지 않으면 이때 사람이 더 많아지면 충분하지 않을 것입니다. 2개를 생산하고 있었습니다. 총 스레드 수는 7개가 되었습니다. 이때 나머지 2명은 기다릴 필요 없이 바로 사용할 수 있습니다. 6명이 오면 이때 내 풀에는 스레드가 5개밖에 남지 않을 수도 있는데, 스레드 5개를 생산할 수 있는데 아직 어딘가에서 기다려야 하는 사람이 한 명 있습니다. 사람들이 무작정 기다리게 할 수는 없습니다. 거기 앉아서 기다리면 됩니다. 그러면 첫 번째 웨이브에서 5명이 스레드가 부족해지고 나머지 1명은 사용할 수 있습니다. 이때 10명이 더 왔어요. 제 스레드는 4명만 앉을 수 있어요. 한 명 남았다면 어떻게 해야 하나요? 여기 자리가 없어요. 먼저 다른 곳을 알아보지 않고 거절하는 건 확실히 불편하고, 몇 가지 거절 전략을 생각해야 해요. . . , 아직 내 스레드 풀을 사용하는 사람들이 많은 것 같습니다. 너무 많은 사람들이 사용하고 있는데 누군가가 내 스레드 풀을 계속 점유하고 있다면 어떻게 해야 할까요? 그렇지 않으면 하나의 스레드를 1분 동안만 사용할 수 있으며 사용 후 즉시 재활용됩니다. 다시 사용하려면 대기열에 넣고 다시 기다리십시오. 이런 식으로 내 스레드 사업은 점점 더 좋아지고 있습니다. 누군가가 그것을 사용하는 한 계속해서 운영될 것입니다.

좀 레스토랑이나 뷔페 같은 느낌이랄까요? 뷔페 매장이 더 시각적이에요. 제 호텔에는 좌석이 있는 한 최대 수용 인원까지만 앉을 수 있어요. 문 앞에서 기다리세요. 손님 한 명이 들어오고, 다른 손님이 밖에서 기다리다가, 더 이상 대기 공간이 없으면 손님은 자리가 없다고 보고 바로 나가곤 합니다. 조금 더 기다릴 수 있어요. 레스토랑에 있는 고객은 약 2시간 정도 너무 오랫동안(보통 자리가 없을 때) 식사를 해서는 안 되며, 식사 후에는 떠나게 됩니다.

위의 설명을 바탕으로 스레드 풀에 무엇이 있는지 확인할 수 있을까요?

스레드 설치 수, 스레드 설치 가능, 스레드 유지 기간, 스레드 대기 영역, 스레드 거부, 생성 방법

Java 스레드 풀의 원리, 사용법 및 성능 최적화 방법은 무엇입니까?

1.1 스레드를 사용하는 이유

프로그램 실행은 반드시 프로세스, 프로세스에 의존 실제 실행 단위는 스레드입니다.

  • 시스템 내 서비스 호출. 시스템은 실행되는 프로세스에 의존합니다. 시스템에는 많은 서비스가 있으며 서비스 간의 상호 작용은 스레드에 의존합니다. 다중 서비스 작업은 다중 스레드 작업에 의존합니다. 서비스 간 호출 및 데이터 교환은 데이터 상호 작용을 위해 프로세스 간 메모리에 의존합니다. 동시에 스레드는 자체 메모리 공간을 구축할 수도 있습니다. 리소스 스케줄링과 프로세스 간 데이터 상호작용에 의존합니다.

  • 다중 스레드는 프로그램의 실행 성능을 향상시킬 수 있습니다. 예를 들어 90㎡의 집이 있다면 한 사람이 청소하는 데는 30분, 세 사람이 청소하는 데는 10분밖에 걸리지 않는다. 이 세 사람이 프로그램 속 '멀티쓰레드'다.

많은 프로그램에서 작업을 병렬로 완료하려면 여러 스레드를 서로 동기화하거나 상호 배타적이어야 합니다.

스레드는 프로세스보다 가볍기 때문에 스레드를 생성하고 삭제하는 데 드는 비용이 줄어듭니다.

스레드는 성능을 향상시킵니다. 스레드는 거시적으로는 병렬이지만 미시적으로는 직렬입니다. 스레드는 CPU 관점에서 성능을 향상시킬 수 없지만 일부 스레드가 리소스 대기(예: IO, 입력 대기)에 관여하는 경우 멀티스레딩을 사용하면 전체 프로세스가 차단되는 대신 프로세스의 다른 스레드가 계속 실행될 수 있으므로 CPU 활용률이 향상되면 이러한 관점에서 성능이 향상됩니다.

멀티 CPU나 멀티 코어의 경우 스레드를 사용하는 것은 매크로 수준뿐만 아니라 마이크로 수준에서도 병렬입니다.

1.2 스레드 풀을 사용하는 이유

다중 스레드를 사용하면 프로그램 실행 성능이 향상될 수 있습니다

  • 예를 들어 뷔페를 먹을 때 좌석과 사람이 충분할 때 뷔페가 가장 수익성이 높습니다. 동시에 식사비와 고객 만족도도 제공할 수 있습니다. 식사하는 사람이 200명이고 식사 장소가 100개 있는데, 한 사람당 평균 한 시간 동안 먹는다면, 200명이 두 시간 안에 식사를 마치게 됩니다. 좌석이 10개뿐이라면 200명이 식사하는 데 약 20시간이 걸릴 것입니다. 나머지 손님들이 초조하게 기다리며 식사를 한다면 얼마나 불행할까요?

  • 뷔페 좌석은 실이 많으면 더 많은 사람이 먹을 수 있지만, 실이 많을수록 좋다는 뜻은 아니고, 결국 매회 200명의 고객이 올지는 확실하지 않습니다. 200명의 고객이 식사하러 오더라도 식당에 요리사가 충분한지, 청소부가 청소를 할 수 있는지, 식당에 접시가 충분한지 등 기본적인 하드웨어 요소도 평가해야 합니다. 이는 메모리, CPU 처리 등 필수 하드웨어 조건이 필요한 시스템 구성과 동일합니다.

스레드 생성/파괴에는 시스템 오버헤드가 수반됩니다. 스레드를 너무 자주 생성/파괴하면 처리 효율성에 큰 영향을 미칩니다(스레드가 계속 실행되는 한 파괴되지 않습니다)

  • 걸리는 시간을 기억하세요. 스레드 T1을 생성하려면 작업을 실행하는 데 시간 T2가 소비되고 스레드를 삭제하는 데 시간 T3이 소비됩니다. T1+T3>T2이면 이 작업을 수행하기 위해 스레드를 여는 것이 비용 효율적이지 않다는 의미입니까? 스레드 풀은 스레드를 캐시하고 기존 유휴 스레드를 사용하여 새 작업을 수행할 수 있으므로 T1+T3으로 인한 시스템 오버헤드를 피할 수 있습니다. 물론 살아남은 코어 스레드도 CPU 리소스를 소비합니다

도 있습니다. 많은 동시 스레드 선점 및 차단 발생

  • 스레드가 시스템 리소스를 공유할 수 있다는 것을 알고 있습니다. 동시에 너무 많은 스레드가 실행되면 시스템 리소스가 부족해 스레드 풀 사용이 발생할 수 있습니다. 위의 문제를 피하기 위해 최대 동시 스레드 수를 효과적으로 제어할 수 있습니다

간단한 스레드 관리를 수행하세요

  • 예: 지연 실행, 타임 루프 실행 전략 등이 스레드를 사용하여 잘 구현될 수 있습니다. pools

1.3, 스레드 풀

스레드 활용도 향상

  • 의 장점 비즈니스가 있을 때 사용하고 비즈니스가 없을 때 해제되도록 보장하세요. 스레드를 합리적으로 사용하여 리소스 낭비를 방지하세요

개선하세요. 프로그램의 응답 속도

  • By 스레드 풀을 균일하게 관리하면 통합된 스케줄링 풀을 사용하여 리소스 할당이 예약됩니다. 스레드를 사용하면 시간이 많이 걸리는 스레드 생성 및 소멸을 피할 수 있으며 스레드를 사용할 수 있습니다. 직접 사용됩니다.

스레드 개체의 통합 관리를 촉진합니다.

  • 스레드 풀은 스레드의 통합 배포 및 관리를 보장합니다.

최대 동시성 수를 제어할 수 있습니다

  • 서버에는 스레드 사용량에 대한 상한이 있으며 스레드 사용량도 많은 리소스를 소비하므로 스레드 풀은 스레드 리소스를 매우 잘 제어하여 낭비를 피할 수 있습니다.

2. Java에서 스레드 풀 사용

ThreadPoolExecutor는 스레드를 풀하는 데 사용할 수 있는 Java의 스레드 풀 클래스입니다.

// 根据上面的描述大概分析一下线程都需要什么及参数的解析
// corePoolSize 核心线程数,就是上面说的装了多少个线程
// maximumPoolSize 最大线程数,就是上面说的能装多少线程
// keepAliveTime 存活时间,就是上面说的线程可以保留多长时间
// TimeUnit 这个是时间单位,有时、分、秒、天等等,是存活时间的单位
// BlockingQueue<Runnable> 这是一个等待队列,就是上面显示的线程等待区
// ThreadFactory 线程工厂,就是上面描述的如何创建线程,由谁创建
// RejectedExecutionHandler 拒绝策略,就是上面显示的如何拒绝,是直接拒绝还是婉拒
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory)
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler)
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)

Java 스레드 풀의 원리, 사용법 및 성능 최적화 방법은 무엇입니까?

보시다시피 다음 매개변수가 필요합니다:

  • corePoolSize(필수): 코어 스레드 수. 기본적으로 코어 스레드는 항상 유지되지만,allowCoreThreadTimeout이 true로 설정되면 코어 스레드도 시간 초과되어 재활용됩니다.

  • maximumPoolSize(필수): 스레드 풀이 수용할 수 있는 최대 스레드 수입니다. 활성 스레드 수가 이 값에 도달하면 후속 새 작업이 차단됩니다.

  • keepAliveTime(필수): 스레드 유휴 시간 초과. 이 시간을 초과하면 코어가 아닌 스레드가 재활용됩니다. AllowCoreThreadTimeout이 true로 설정된 경우 코어 스레드도 시간 초과되어 재활용됩니다.

  • unit(필수): keepAliveTime 매개변수의 시간 단위를 지정합니다. 일반적으로 사용되는 것은 TimeUnit.MILLISECONDS(밀리초), TimeUnit.SECONDS(초), TimeUnit.MINUTES(분)입니다.

  • workQueue(필수): 작업 대기열. 스레드 풀의 Execute() 메소드를 통해 제출된 실행 가능 객체는 이 매개변수에 저장됩니다. 블로킹 큐를 사용하여 구현됩니다.

  • threadFactory(선택 사항): 스레드 팩토리. 스레드 풀에 대해 새 스레드가 생성되는 방법을 지정하는 데 사용됩니다.

  • 핸들러(선택 사항): 거부 전략. 최대 스레드 수에 도달했을 때 실행해야 하는 포화 전략입니다.

2.1. 스레드 풀의 작동 원리

Java 스레드 풀의 원리, 사용법 및 성능 최적화 방법은 무엇입니까?

2.2. 스레드 풀의 Java 코드 예

import java.util.concurrent.*;
public class ThreadTest {
    public static void main(String[] args) {
        ExecutorService threadPoolExecutor = new ThreadPoolExecutor(3, 5, 1L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory());
        for (int i = 0; i < 20; i++) {
            int finalI = i;
            threadPoolExecutor.submit( ()->{
                System.out.println(Thread.currentThread().getName() + "========" + finalI);
            });
        }
        threadPoolExecutor.shutdown();
    }
}

실행 결과:

풀-1-스레드-1=========0
풀-1-스레드-3=========2
풀-1-스레드-3======= =4
풀-1-스레드-2========1
풀-1-스레드-3==========5
풀-1-스레드-2====== ==8
풀-1-스레드-5=========7
풀-1-스레드-1==========3
풀-1-스레드-4===== ===6
스레드 "main"의 예외 java.util.concurrent.RejectedExecutionException: java.util.concurrent.ThreadPoolExecutor@66cd51c3[실행 중, 풀 크기 = 5, 활성 스레드에서 작업 java.util.concurrent.FutureTask@61e717c2가 거부되었습니다. = 2, 대기 중인 작업 = 0, 완료된 작업 = 7]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830 )
java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
com.halo.communication.ThreadTest.main(ThreadTest) .java:10)

执行的线程数超过了线程池可容纳的大小, 线程池使用默认拒绝策略拒绝多余线程执行,然后开始出现异常处 logic.상면 이동형 线程数到thread-5,5是线程池的默认最大线程数。 2020년을 위한 멋진 여행 ,所以线程池执行拒绝策略。

위 내용은 Java 스레드 풀의 원리, 사용법 및 성능 최적화 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제