Trong bài này, chúng ta sẽ tìm hiểu cách lập trình đa luồng (multithreading) trong Java. Để làm cơ sở học tốt bài này, các bạn nên đọc bài Thread là gì? Cách tạo Thread trong Java để có kiến thức cơ bản về Thread nhé.
1. Lập trình mutilthreading trong Java
Java hỗ trợ lập trình multithreading, cho phép thực thi đồng thời hai hoặc nhiều Thread trong một tiến trình (Process) nhằm tận dụng tối đa sức mạnh của CPU (số nhân, số luồng).
Một phần mềm thì có thể có nhiều Process. Mỗi Process thì có thể có nhiều Thread. Những Thread này sẽ được đưa vào các Core của CPU để xử lý. Nếu CPU được tích hợp công nghệ Hyper-Threading thì mỗi Core của CPU có thể xử lý được 2 Thread cùng lúc.
2. Ưu điểm khi lập trình multithreading
– Tận dụng được tối đa sức mạnh của CPU, giúp chương trình có thể xử lý nhiều công việc cùng một lúc. Từ đó, multithreading giúp chương trình được xử lý nhanh hơn.
– Mỗi Thread có thể dùng chung và chia sẻ nguồn tài nguyên trong cùng một Process nhưng mỗi Thread được thực hiện một cách độc lập. Vì thế, nếu một Thread xảy ra ngoại lệ (exception) thì không ảnh hưởng đến các Thread khác.
3. Nhược điểm khi lập trình multithreading
– Khi có càng nhiều Thread thì xử lý càng phức tạp. Các vấn đề về tranh chấp bộ nhớ, đồng bộ dữ liệu cần được chú ý xử lý tốt nếu không có thể phát sinh lỗi cho chương trình.
– Cần phát hiện trường hợp mà 2 hoặc nhiều Thread rơi vào tình trạng blocked, chờ đợi lẫn nhau. Lý do là mỗi Thread giữ một tài nguyên và chờ đợi tài nguyên từ Thread khác, chờ mãi mà không Thread nào được thực thi. Trường hợp này gọi là Deadlock.
– Cũng cần phát hiện các Thread chạy mà không làm gì trong ứng dụng, sẽ gây tốn tài nguyên bộ nhớ, CPU của máy tính.
4. Ví dụ về lập trình multithreading trong Java
Trong ví dụ bên dưới, chúng ta sẽ tạo ra 3 Thread. Mỗi Thread có nhiệm vụ in ra các số từ 1 đến 5 và được định nghĩa trong hàm run()
. Chúng ta tạo ra các Thread và gọi hàm start()
để bắt đầu thực thi các Thread. Lúc này, 3 Thread sẽ chạy cùng lúc. Kết quả các lần chạy chương trình cho thấy rõ điều đó.
class A extends Thread{
@Override
public void run(){
for(int i=1;i<=5;i++){
System.out.println("\t From ThreadA: i= "+i);
}
System.out.println("Exit from A");
}
}
class B extends Thread {
@Override
public void run() {
for(int j=1;j<=5;j++) {
System.out.println("\t From ThreadB: j= "+j);
}
System.out.println("Exit from B");
}
}
class C extends Thread {
@Override
public void run() {
for(int k=1;k<=5;k++) {
System.out.println("\t From ThreadC: k= "+k);
}
System.out.println("Exit from C");
}
}
class MyThread{
public static void main(String args[]){
new A().start();
new B().start();
new C().start();
}
}
Chạy lần 1
From ThreadA: i= 1
From ThreadA: i= 2
From ThreadA: i= 3
From ThreadB: j= 1
From ThreadB: j= 2
From ThreadB: j= 3
From ThreadA: i= 4
From ThreadC: k= 1
From ThreadA: i= 5
Exit from A
From ThreadB: j= 4
From ThreadB: j= 5
Exit from B
From ThreadC: k= 2
From ThreadC: k= 3
From ThreadC: k= 4
From ThreadC: k= 5
Exit from C
Chạy lần 2
From ThreadA: i= 1
From ThreadA: i= 2
From ThreadA: i= 3
From ThreadA: i= 4
From ThreadA: i= 5
Exit from A
From ThreadB: j= 1
From ThreadC: k= 1
From ThreadB: j= 2
From ThreadC: k= 2
From ThreadC: k= 3
From ThreadC: k= 4
From ThreadC: k= 5
Exit from C
From ThreadB: j= 3
From ThreadB: j= 4
From ThreadB: j= 5
Exit from B
Khi các Thread chạy cùng lúc thì chúng sẽ tiêu tốn bộ nhớ RAM và tài nguyên xử lý của CPU. Để kiểm tra xem chúng ta đang có lập trình multithreading hay không thì cách kiểm tra đơn giản là hãy kiểm tra phần trăm sử dụng CPU (CPU usage percentage).
Ví dụ, chúng ta sửa nhiệm vụ của các Thread trong chương trình trên là in các số từ 1 đến 5000000, rồi cho 3 Thread chạy cùng lúc. Các bạn sẽ thấy phần trăm sử dụng CPU lên đến gần 100% hoặc 100%. Lúc này, các bạn để ý thấy khi CPU hoạt đồng hết công suất thì quạt tản nhiệt của CPU sẽ quay mạnh hơn.