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é.
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 :
- Như em nói ở trên dùng @Async và ThreadPool
- 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