Avatar
1
Hihi Teacher
Hihi Teacher
ThreadPool trong Java
Hi mọi người, hiện tại em có làm 1 chức năng khá tốn nhiều thời gian để xử lý  nên em đã áp dụng multi thread mục đích là để xứ lí chức năng đó ở 1 thread khác và để thread chính ko bị treo => trả response về cho client.Cụ thể là sử dụng @Async và có sử dụng thêm ThreadPoolTaskExecutor để cố định size của ThreadPool.

Cho em hỏi là trong thực tế thì người ta sẽ dựa vào những yếu tố nào để cấu hình cho các thuộc tính của ThreadPoolTaskExecutor  ví dụ như là: CorePoolSize, MaxPoolSize, QueueCapacity, KeepAliveSeconds,.... để đạt được hiểu quả nhất ạ?

(Em đoán có thể là phần cứng của server có đúng ko ạ  )

Theo em nghĩ nếu cấu hình quá nhiều hoặc quá ít Thread thì hiệu năng sẽ có thể bị ảnh hưởng.

Cảm ơn mọi người !

  • Answer
threadpool executor
Remain: 5
1 Answer
Avatar
monkey Teacher
monkey Teacher
Câu hỏi này rất hay được hỏi trong khi phỏng vấn mà đôi khi chính người phỏng vấn cũng không trả lời được.

Đầu tiên phải khẳng định là multi-thread chưa chắc đã giúp cho chương trình của chúng ta hoạt động nhanh hơn, đặc biệt là trong các nghiệp vụ xử ngoài I/O, ví dụ bây giờ dùng 2 thread để cộng kiểu:

thread 1: t1 = a + b;
thread 2: t2 = c + d;
main thread: chờ cho thread 1 và thread 2 xong thì cộng t = t1 + t2

so với cộng trực tiếp: t = a + b + c + d

Thì chưa chắc multi-thread đã nhanh hơn bởi vì vấn đề của multi-thread là nó còn tốn thời gian để switch-context.

Như vậy thì multi-thread thì sẽ chỉ có tác dụng lớn đối với các chương trình có xử lý I/O nhiều, bây giờ quay trở lại câu hỏi của em.

Việc tạo ra bao nhiêu thread đúng là có phụ thuộc vào phần cứng, ví dụ như 1 thread của java sẽ đi kèm với 1 cái stack call khoảng 2MB, vậy em sẽ không nên tạo ra 1000 cái thread cho 1 server chỉ có 2GB RAM, rất có thể nó sẽ gây tràn bộ nhớ.

Tiếp theo là có cần căn cứ theo số core của CPU để tạo thread không? Câu trả lời là không chắc, nó còn tuỳ thuộc vào hệ điều hành, ví dụ như bọn anh đang dùng Centos, cho dù anh có tạo ra bao nhiêu thread thì nó cũng chỉ dùng có đúng 1 core (anh cũng không chắc là mình đang dùng sai cấu hình hay gì không, nhưng khi nhìn trên metrics thì lúc nào nó cũng chỉ dùng đúng 1 core). Vậy nên không phải em càng dùng nhiều thread thì sẽ tận dụng được nhiều core đâu.

Tiếp theo có phải chương trình mình bị treo thì mình càng tạo nhiều thread để đáp ứng kiểu Async kia không? Câu trả lời chắc chắn là không, bởi vì khi sử dụng kiểu Async kia chẳng quan là nó sẽ chuyển request vào 1 thread pool khác để giải phóng cho cái thread nhận request mà thôi, vậy nên càng nhiều request thì càng chậm, queue của thread pool async sẽ ngày càng tăng từ đó làm tăng RAM, và đến 1 lúc nào đó quá capacity của queue thì request cũng sẽ bị từ chối. Nên ngay cả khi dùng Async thì em vẫn phải kiểm soát số lượng request đến để đảm bảo khả năng phục vụ nhé.

  • 0
  • Reply
Tks a vì câu trả lời !

Em có dùng @KafkaListener để nhận tin nhắn sau đó gửi gmail (tốn nhiều thời gian) cho user.Em dùng đa luồng cho chức năng này để giải quyết vấn đề treo thread khi xử lý trong listener (do listener mặc định có 1 thread )

Em có 2 lựa chọn :

  1. Như em nói ở trên dùng @AsyncThreadPool
  2. Cấu hình số luồng của listener thông qua setConcurrency (như bên dưới)
@Bean

public KafkaListenerContainerFactory

<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() {

ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();

factory.setConsumerFactory(consumerFactory());

factory.setConcurrency(5);

......

}

Anh cho em hỏi 2 cách này có em nên dùng cách nào hiệu quả hơn và vì sao ạ hoặc n ếu anh có cách nào hay hơn  thì mong anh recommend cho em với ạ.

 –  Hihi 1664166726000
Em có thế tách ra thành câu hỏi khác giúp anh đc ko em?  –  dungtv 1664167225000
Em vừa đăng rồi đó anh ạ  –  Hihi 1664177646000