Thread pool là gì

     

Trong bài trước, các bạn đã được học về phong thái sử dụng sleep() với join(). Sang bài này, tôi đang hướng dẫn các bạn tìm hiểu phương pháp tạo và sử dụng ThreadPool. Các bạn theo dõi nhé!

*


*

1. ThreadPool là gì?

Trong Java, ThreadPool được dùng để làm giới hạn số lượng Thread được chạy bên phía trong ứng dụng của chúng ta trong cùng một thời điểm. Nếu họ không bao gồm sự giới hạn này, mỗi lúc có một Thread mới được tạo nên và được cung cấp phát bộ lưu trữ bằng trường đoản cú khóa new thì sẽ có được vấn đề về bộ nhớ và hiệu suất, hoàn toàn có thể dẫn mang lại lỗi crash chương trình.

Bạn đang xem: Thread pool là gì

Ví dụ: Khi chúng ta viết lịch trình tải những tập tin tự Internet, từng tập tin đề nghị 1 Thread nhằm thực hiện quy trình tải, trả sử phải tải 1000 tệp hình hình ảnh thì chúng ta phải đề nghị tới 1000 Thread hoạt động cùng 1 thời điểm trong và một chương trình. Điều này đã dễ dẫn mang đến lỗi quá download của chương trình, làm ảnh hưởng đến năng suất và chương trình sẽ tương đối dễ bị crash bởi khó kiểm soát.

Vì vậy, nhằm khắc phục hiện tượng lạ này, Java đến phép bọn họ thay vì phải khởi tạo mới Thread cho mỗi nhiệm vụ, quy trình được triển khai trong cùng 1 thời điểm thì các nhiệm vụ, quá trình đó có thể được gửi vào trong một ThreadPool để khi vào ThreadPool có ngẫu nhiên Thread nào đang không phải triển khai một trách nhiệm nào thì sẽ có được nhiệm vụ gán vào một trong số các Thread đó nhằm thực thi. Điều này để giúp khắc phục được sự tắc nghẽn và lịch trình sẽ kiểm soát điều hành được những luồng thực thi.

Bài viết này được đăng tại


Bên trong ThreadPool, các nhiệm vụ sẽ được chèn vào trong một Blocking Queue. Blocking Queue có thể hiểu là chỗ chứa những nhiệm vụ mà những Thread đã lấy chúng ra và xúc tiến lần lượt. Mỗi khi có một trách nhiệm mới được sản xuất Queue và sau đó sẽ chỉ bao gồm một Thread đang không phải tiến hành một nhiệm vụ nào vào Queue lấy nhiệm vụ đó ra, còn các Thread sót lại phải hóng đợi cho đến khi Thread kia lấy nhiệm vụ ra thành công.

Xem thêm: Nghi Thức Lễ Gia Tiên Là Gì, Lễ Gia Tiên Đám Cưới Truyền Thống Gồm Những Gì

Ví dụ dưới đây sẽ minh họa biện pháp tạo ThreadPool bằng cách sử dụng ThreadPoolExecutor:


RunPool.java

package vidu;public class RunPool implements Runnable int id;
Overridepublic void run() System.out.println("Đang xử lý các bước " + id);try Thread.sleep(1000); catch (InterruptedException e) e.printStackTrace();System.out.println("Đã xử lý quy trình " + id);public RunPool(int id) this.id = id;
MyThreadPool.java

package vidu; import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit; public class MyThreadPool { public static void main(String<> args) ArrayBlockingQueue hangDoi = new ArrayBlockingQueue(100); // khi số tiến trình của chúng ta vượt quá maxSize ở đây là 5// ví dụ như đối số trước tiên = 6// thì toàn bộ những quá trình mới mà họ tạo ra sẽ được đưa vào hangDoiThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 12, TimeUnit.SECONDS, hangDoi);// sử dụng vòng lặp for để có thể chạy những Threadfor (int i = 0; i

Kết quả sau khoản thời gian biên dịch chương trình:

Giải thích hoạt động của chương trình trên:

Trong mẫu code khởi sinh sản ThreadPoolExecutor: ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 1, TimeUnit.SECONDS, hangDoi); chúng ta có 5 tham số:

Đối hàng đầu (corePoolSize) là số lượng Thread buổi tối thiểu vào ThreadPool, ở chỗ này corePoolSize = 5. Khi khởi tạo, con số Thread hoàn toàn có thể là 0. Khi nhiệm vụ được cấp dưỡng thì Thread new được tạo ra và tính từ lúc đây, nếu con số Thread thấp hơn corePoolSize thì các Thread mới sẽ được tạo ra đến khi số Thread bởi giá trị của corePoolSize.Đối số 2 (maximumPoolSize) là con số tối đa những Thread trong ThreadPool.Đối số 3 (keepAliveTime): khi số Thread lớn hơn corePoolSize thì keepAliveTime là thời hạn tối đa nhưng 1 Thread "nhàn rỗi" chờ nhiệm vụ. Lúc hết thời hạn chờ nhưng Thread đó chưa có nhiệm vụ thì nó có khả năng sẽ bị hủy.Đối số 4 (unit) là 1-1 vị thời hạn của keepAliveTime. Trong lấy ví dụ này thì unit của tớ là TimeUnit.SECONDS.Đối số 5 (workQueue) là hàng đợi dùng để chứa các nhiệm vụ mà những Thread sẽ lấy chúng ra và xúc tiến lần lượt, tại đây tôi sử dụng ArrayBlockingQueue.

2. ExecutorService

Kể từ Java 5 trở đi, ThreadPool đã được kiến thiết sẵn trong gói java.util.concurrent, bởi vì vậy bọn họ không cần phải tạo một ThreadPool mà thế vào đó chúng ta sẽ sử dụng các lớp bao gồm sẵn của gói này. Java hỗ trợ cho chúng ta lớp Executor, interface của lớp Executor là ExecutorService.

Ta hoàn toàn có thể tạo ThreadPool trải qua Interface ExecutorService, những nhiệm vụ sẽ được đưa vào ThreadPool cùng được xử trí bằng giữa những phương thức gồm sẵn nhưng mà Executor cung ứng như sau:

newSingleThreadExecutor(): trong ThreadPool chỉ có 1 Thread và các nhiêm vụ sẽ được xử lý một cách tuần tự.newCachedThreadPool(): vào ThreadPool sẽ có tương đối nhiều Thread và các nhiệm vụ sẽ tiến hành xử lý một cách tuy vậy song. Những Thread cũ sau thời điểm xử lý kết thúc sẽ được thực hiện lại cho trọng trách mới. Mang định ví như một Thread ko được sử dụng trong vòng 60 giây thì Thread đó có khả năng sẽ bị tắt.newFixedThreadPool(): trong ThreadPool sẽ được cố định và thắt chặt các Thread. Giả dụ một trách nhiệm mới được gửi vào mà những Thread phần đông đang "bận rộn" thì nhiệm vụ đó sẽ tiến hành gửi vào Blocking Queue và kế tiếp nếu gồm một Thread sẽ thực thi dứt nhiệm vụ của chính nó thì trọng trách đang sinh sống trong Queue đó sẽ tiến hành push ra khỏi Queue và được Thread đó xử trí tiếp.newScheduledThreadPool(): tựa như như newCachedThreadPool() nhưng sẽ có thời gian delay giữa các Thread.newSingleThreadScheduledExecutor(): giống như như newSingleThreadExecutor() nhưng sẽ sở hữu được khoảng thời hạn delay giữa các Thread.

Interface ExecutorService đại diện thay mặt cho cơ chế thực thi bất đồng bộ có công dụng thực thi những nhiệm vụ trong background (nền). ExecutorService tựa như như một ThreadPool và trong thực tế, việc triển khai ExecutorService là 1 trong triển khai ThreadPool.

Xem thêm: Giá Trị Nội Dung Của Bài Thơ Nhàn Là Gì ? Giá Trị Nội Dung Của Bài Thơ Nhàn Là Gì

Sau đây tôi sẽ đưa ra một ví dụ như minh họa cách thực hiện ExecutorService:


Overridepublic void run() System.out.println("Đang xử lý tiến trình " + id);try Thread.sleep(1000); catch (InterruptedException e) e.printStackTrace();System.out.println("Đã xử lý quy trình " + id);public RunPool(int id) this.id = id;

package vidu; import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit; public class MyThreadPool { public static void main(String<> args) { ExecutorService pool = Executors.newFixedThreadPool(5);for (int i = 0; i

Kết quả sau khi biên dịch chương trình:

Lưu ý: bạn nên shutdown một ThreadPool bằng phương pháp gọi cách thức shutdown() cũng chính vì ta không thể chắc chắn là được rằng thứ ảo Java có thể tự động hóa làm điều đó.

3. Lời kết

Trong bài này, tôi đang hướng dẫn các bạn tìm hiểu về phong thái tạo và sử dụng ThreadPool.Sang bài xích sau, tôi sẽ trình diễn các phần còn sót lại liên quan mang đến Thread. Các bạn theo dõi nhé!