머리말
이전 기사는 백엔드 서비스 데이터베이스 및 다중 스레드 병렬 처리의 최적화 및 변환 전후의 의사 코드 로직의 예에 중점을 둡니다. 물론 최적화는 끝이 없습니다. 이전 세대 식물 나무와 후반 세대는 그늘을 즐깁니다. 우리가 개발자로서, 우리는 거인의 어깨에 서 있기 때문에보다 최적화 된 프로그램을 작성해야합니다.
SpringBoot 개발 케이스 JDBCTEMPLATE 배치 작업
SpringBoot 개발 사례 : CountdownLatch 멀티 태스킹 병렬 처리
혁신
이론적으로, 스레드가 많을수록 프로그램이 더 빨라질 수 있지만 실제로 사용하면 스레드 자체의 자원 소비와 파괴의 자원 소비와 운영 체제 자체를 보호하기위한 목적을 고려해야합니다. 우리는 일반적으로 스레드를 특정 범위로 제한해야하며 스레드 풀이이 역할을합니다.
프로그램 논리
멀티 태스킹 병렬 + 스레드 풀 프로세싱 .png
그림으로 해결할 수있는 문제는 가능한 한 적어야합니다. 물론, 근본적인 원칙은 여전히 모든 사람이 기억하고 이해해야합니다.
자바 스레드 풀
Java는 집행자를 통해 4 가지 유형의 스레드 풀을 제공합니다.
이점
코드 구현
방법 1 (CountdownLatch)
/*** 멀티 태스킹 병렬 + 스레드 풀 통계* 생성 시간 2018 년 4 월 17 일*/public class statsdemo {Final STATIC SMEPLEDATEFORMAT SDF = New SimpledateFormat ( "YYYY-MM-DD HH : MM : SS"); 최종 정적 문자열 startTime = sdf.format (new date ()); / ** * IO 집약적 인 작업 = 일반적으로 2 * CPU 코어 수 (종종 스레드에서 : 데이터베이스 데이터 상호 작용, 파일 업로드 및 다운로드, 네트워크 데이터 전송 등) * CPU 강성 작업 = 일반적으로 1 CPU CORES + 1 (종종 스레드 : 복잡한 알고리즘) * 시스템 구성 및 복잡성에 따라 하이브리드 작업 = 시스템 구성 */ Private int Core-POOL. runtime.getRuntime (). avideprocessors (); /*** Public ThreadPooleExecutor (int corepoolsize, int maximumpoolsize, long recoyalivetime,* timeUnit 단위, blockingqueue <runnable> workqueue)* corepoolsize는 핵심 스레드의 수를 지정하는 데 사용됩니다. 스레드 풀의 버퍼 큐와 아직 실행되지 않은 스레드는 큐* 모니터 큐 길이에서 대기하여 큐 경계* 부적절한 스레드 풀 크기가 처리 속도를 늦추고 안정성을 줄이며 메모리 누출로 이어질 수 있는지 확인합니다. 구성된 스레드가 너무 적으면 대기열이 계속 커지고 메모리가 너무 많이 소비됩니다. * 너무 많은 스레드가 컨텍스트 전환이 빈번하여 전체 시스템의 속도를 늦출 수 있으며 동일한 최종 결과가 달성됩니다. 대기열의 길이는 중요합니다. 스레드 풀이 압도되면 일시적으로 새로운 요청을 거부 할 수 있도록 경계를 유지해야합니다. * ExecutorService의 기본 구현은 무한한 링크드 블로킹 Queue입니다. */ private static strandpoolexecutor executor = new ThreadPoolexecutor (CorePoolSize, CorePoolSize+1, 10L, TimeUnit.seconds, 새로운 LinkedBlockingQueue <Runnable> (1000)); public static void main (string [] args)은 중단 된 출시 {countdownlatch latch = new CountdownLatch (5); // execute method executor.execute를 사용합니다 (새 통계 ( "task a", 1000, latch)); Executor.Execute (새 통계 ( "작업 B", 1000, Latch)); Executor.Execute (새 통계 ( "작업 C", 1000, Latch)); executor.Execute (새 통계 ( "작업 d", 1000, 래치)); executor.Execute (새 통계 ( "작업 E", 1000, 래치)); latch.await (); // 모든 사람의 작업이 System.out.println을 종료 할 때까지 기다립니다 ( "모든 통계 작업 실행이 완료되었습니다 :" + sdf.format (new Date ()); } 정적 클래스 통계를 구현할 수있는 {String StatsName; int 런타임; CountdownLatch 래치; 공개 통계 (문자열 통계 이름, int 런타임, CountdownLatch Latch) {this.statsname = statsname; this.runtime = 런타임; this.latch = 래치; } public void run () {try {system.out.println (statsname+ "do stats 시작"+ startTime에서 시작); // 작업 실행 시간을 시뮬레이션합니다. System.out.println (statsname + "Do Stats는" + sdf.format (new date ())에서 완료합니다. latch.countdown (); // 단일 작업 종료가 끝나고 카운터가 One} Catch (InterruptedException e) {e.printstacktrace (); }}}}방법 2 (미래)
/*** 멀티 태스킹 병렬 + 스레드 풀 통계* 생성 시간 2018 년 4 월 17 일*/public class statsdemo {Final STATIC SMEPLEDATEFORMAT SDF = New SimpledateFormat ( "YYYY-MM-DD HH : MM : SS"); 최종 정적 문자열 startTime = sdf.format (new date ()); / ** * IO 집약적 인 작업 = 일반적으로 2 * CPU 코어 수 (종종 스레드에서 : 데이터베이스 데이터 상호 작용, 파일 업로드 및 다운로드, 네트워크 데이터 전송 등) * CPU 강성 작업 = 일반적으로 1 CPU CORES + 1 (종종 스레드 : 복잡한 알고리즘) * 시스템 구성 및 복잡성에 따라 하이브리드 작업 = 시스템 구성 */ Private int Core-POOL. runtime.getRuntime (). avideprocessors (); /*** Public ThreadPooleExecutor (int corepoolsize, int maximumpoolsize, long recoyalivetime,* timeUnit 단위, blockingqueue <runnable> workqueue)* corepoolsize는 핵심 스레드의 수를 지정하는 데 사용됩니다. 스레드 풀의 버퍼 큐와 아직 실행되지 않은 스레드는 큐* 모니터 큐 길이에서 대기하여 큐 경계* 부적절한 스레드 풀 크기가 처리 속도를 늦추고 안정성을 줄이며 메모리 누출로 이어질 수 있는지 확인합니다. 구성된 스레드가 너무 적으면 대기열이 계속 커지고 메모리가 너무 많이 소비됩니다. * 너무 많은 스레드가 컨텍스트 전환이 빈번하여 전체 시스템의 속도를 늦출 수 있으며 동일한 최종 결과가 달성됩니다. 대기열의 길이는 중요합니다. 스레드 풀이 압도되면 일시적으로 새로운 요청을 거부 할 수 있도록 경계를 유지해야합니다. * ExecutorService의 기본 구현은 무한한 링크드 블로킹 Queue입니다. */ private static strandpoolexecutor executor = new ThreadPoolexecutor (CorePoolSize, CorePoolSize+1, 10L, TimeUnit.seconds, 새로운 LinkedBlockingQueue <Runnable> (1000)); public static void main (string [] args)은 인터럽트 exception {list <future <string>> resultList = new arrayList <future <string>> (); // 비동기 작업 제출을 사용하고 향후 resultList.Add (Executor.Submit (새 통계 ( "작업 A", 1000)))로 반환 값을 얻습니다. resultList.add (Executor.Submit (새 통계 ( "작업 B", 1000))); resultList.Add (Executor.Submit (새 통계 ( "Task C", 1000))); resultList.Add (Executor.Submit (새 통계 ( "Task D", 1000))); resultList.add (Executor.Submit (새 통계 ( "작업 E", 1000))); // (Future <string> fs : resultList)에 대한 트래버스 작업 결과 {try {system.out.println (fs.get ()); // 각 라인 작업 실행 결과를 인쇄하고 미래.get ()을 호출하여 기본 스레드를 차단하고 비대형 작업} CATC (InterruptedSception e) {E.PrintStactCtrace () {E.PrintStacktrace (); } catch (executionException e) {e.printstacktrace (); } 마침내 {// 한 번 시작하고 이전에 제출 된 작업을 실행하지만 새 작업을 수락하지 마십시오. 폐쇄 된 경우 전화는 다른 효과가 없습니다. executor.shutdown (); }} system.out.println ( "모든 통계 작업이 실행됩니다." + sdf.format (new date ()); } 정적 클래스 통계를 구현할 수있는 <string> {문자열 statsname; int 런타임; public stats (String statsname, int runtime) {this.statsname = statsname; this.runtime = 런타임; } public string call () {try {system.out.println (statsname+ "스탯은"+ startTime에서 시작); // 작업 실행 시간을 시뮬레이션합니다. System.out.println (statsname + "Do Stats는" + sdf.format (new date ())에서 완료합니다. } catch (InterruptedException e) {e.printstacktrace (); } return Call (); }}}실행 시간
위의 코드는 모두 의사 코드이며 다음은 2,000 명 이상의 학생들에 대한 실제 테스트 레코드입니다.
2018-04-17 17 : 42 : 29.284 정보 테스트 레코드 81E51AB031EB4ADA92743DDF66528D82-SILLE-STHREADED SERCENTION 실행, 시간 : 3797
2018-04-17 17 : 42 : 31.452 정보 테스트 레코드 81E51AB031EB4ADA92743DDF66528D82-MULTI-STREAD PAREMATION 작업, 2167
2018-04-17 17 : 42 : 42 : 33.170 정보 테스트 레코드 81E51AB031EB4ADA92743DDF66528D82-MULTI-STREAD PAREMATION 작업 + 스레드 풀, 시간 : 1717
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.