Đa luồng trong java
1. Thread là gì? Multi-thread là gì?
- Thread là một tiến trình đơn vị xử lý của máy tính có thể thực hiện một công việc riêng biệt. Trong Java các luồng được quản lý bởi máy ảo Java (JVM).
- Multi-thread là khái niệm cho nhiều tiến trình chạy đồng thời. Một ứng dụng Java ngoài luồng chính có thể có các luồng khác thực thi đồng thời làm ứng dụng chạy nhanh và hiệu quả hơn.
VD: Trong một game đánh nhau có 2 người chơi thì mỗi người chơi sẽ do 1 luồng quản lý. Các hoạt cảnh game có thể do một luồng khác quản lý. Làm cho game trở nên sinh động.
2. Cách tạo luồng trong Java
Có 2 cách tạo 1 luồng trong Java:
Cách 1: Kế thừa từ Thread
public class MyThread extends Thread {
public void run(){
System.out.println("Thread 1 đang chạy");
}
}
Chạy Thread:
MyThread myThread = new MyThread();
myTread.start();
Cách 2: Implement Interface Runnable hoặc Callable
public class MyRunnable implements Runnable {
public void run(){
System.out.println("Thread Runnable đang chạy");
}
}
Chạy Thread Runnable:
Thread thread = new Thread(new MyRunnable());
thread.start();
* Dùng callable trong trường hợp muốn trả về giá trị khi Thread thực hiện xong
public class MyCallable implements Callable
public String call(){
return "Kết quả trả về";
}
}
* Vậy khi nào dùng cách 2 và khi nào dùng cách 1?
Ở đây 2 cách đều như nhau, nhưng thường dùng cách 2 cho những trường hợp đa kế thừa. Chú ý trong java ta không thể kế thừa 2 class nhưng có thể implement nhiều Interface.
3. Vòng đời của Thread (Life cycle )
* New: Đây là trạng thái khi luồng vừa được khởi tạo bằng phương thức khởi tạo của lớp Thread nhưng chưa được start(). Ở trạng thái này, luồng được tạo ra nhưng chưa được cấp phát tài nguyên và cũng chưa chạy. Nếu luồng đang ở trạng thái này mà ta gọi các phương thức ép buộc stop,resume,suspend … sẽ là nguyên nhân sảy ra ngoại lệ IllegalThreadStateException .
* Runnable: Sau khi gọi phương thức start() thì luồng test đã được cấp phát tài nguyên và các lịch điều phối CPU cho luồng test cũng bắt đầu có hiệu lực. Ở đây, chúng ta dùng trạng thái là Runnable chứ không phải Running, vì như đã nói ở phần đầu (Các mô hình đa luồng) thì luồng không thực sự luôn chạy mà tùy vào hệ thống mà có sự điều phối CPU khác nhau.
* Running: Luồng đang chạy và CPU có trong lịch trình điều phối của CPU.
* Non-Runnable (Blocked): Luồng đã thực hiện xong nhưng vẫn còn sống.
* Terminated: Luồng đã chết khi thoát khỏi hàm run()
4. Ưu nhược điểm của đa luồng:
* Ưu điểm của đa luồng:
- Mỗi luồng có thể dùng chung và chia sẻ nguồn tài nguyên trong quá trình chạy, nhưng có thể thực hiện một cách độc lập.
- Ứng dụng trách nhiệm có thể được tách
+ Luồng chính chạy giao diện người dung
+ Các luồng phụ nhiệm gửi đến luồng chính.
- Luồng mang tính chất trừu tượng
- Một chương trình đa luồng hoạt động nhanh hơn trên máy tính có cấu hình tốt và mạnh
* Nhược điểm của đa luồng:
- Càng nhiều luồng thì xử lý càng phức tạp
- Cần phát hiện tránh các luồng chết, luồng chạy mà không làm gì trong ứng dụng cả
5. DEMO Ứng Dụng Producer Consumer
*Mô Hình
PRODUCER --------> |||||QUEUE||||| ----------> CONSUMER
- Producer liên tục tạo ra sản phẩm bỏ vào kho (Queue). Nếu kho đầy thì đợi.
- Consumer kiểm tra sản phẩn có trong kho nếu có thì thực hiện lấy sản phẩm ra. Không có thì đợi.
* Producer.java
public class Producer extends Thread{
private BoundedBufferQueue content; //khai bao kho
public Producer(BoundedBufferQueue content) {
this.content = content;
}
@Override
public void run() {
while(true){
Random r = new Random();
int product = (int)(r.nextInt(100));//tao san pham tu 0->99
content.addProduct(product);
}
}
}
Consumer.java
public class Consumer extends Thread{
private BoundedBufferQueue content; //khai bao kho
public Consumer(BoundedBufferQueue content) {
this.content = content;
}
@Override
public void run() {
while(true){
int x = content.getProduct(); //lay 1 sp ra khoi kho
if(x != Integer.MIN_VALUE)
System.out.println("Consumer get: " + x);
}
}
}
BoundedBufferQueue.java
public class BoundedBufferQueue {
private int arr[]; // mang luu tru san pham (kho)
private int max; //size cua mang
private static int lastPosition = 0;//luu vi tri san pham cuoi cung
/**
* contractor khoi tao khi new mot BoundedBufferQueue
*/
public BoundedBufferQueue(int maxN) {
max = (maxN > 0)? maxN : 100;
arr = new int[max];//tao mang max phan tu
}
//them san pham vao kho
public synchronized void addProduct(int value){
try{
if(isFull()){//neu Kho day San pham
Thread.currentThread().wait();//dung thread add SP
} else {
arr[lastPosition] = value; //add sp vao Kho
lastPosition++; //tang vi tri chua sp len 1
System.out.println("Producer add: "+value +" ");
}
notifyAll();
}catch(Exception e){}
}
//lay san pham
public synchronized int getProduct(){
int result = Integer.MIN_VALUE; //san pham duoc ban
try{
if(isEmpty()) //neu mang trong
Thread.currentThread().wait(); //thread lay SP doi
else if(lastPosition > 0){
result = arr[0]; //lay san pham dau tien
for(int i=0; i < lastPosition - 1; i++)
arr[i] = arr[i+1]; //day cac sp phia sau len truoc
lastPosition--;
}
notifyAll();
}catch(Exception e){}
return result;
}
public boolean isFull(){
return lastPosition == max;
}
public boolean isEmpty(){
return lastPosition == 0;
}
public static int getLastPosition() {
return lastPosition;
}
}
Main.java
/**
* @param args the command line arguments
*/
public class Main {
public static void main(String[] args) {
BoundedBufferQueue kho = new BoundedBufferQueue(5);//tao kho 5 SP
Producer p = new Producer(kho);
Producer p2 = new Producer(kho);
Consumer c = new Consumer(kho);
p.start();
p2.start();
c.start();
}
}
Bạn đang muốn tìm kiếm 1 công việc với mức thu nhập cao.
✅ Hoặc là bạn đang muốn chuyển đổi công việc mà chưa biết theo học ngành nghề gì cho tốt.
✅ Giới thiệu với bạn Chương trình đào tạo nhân sự dài hạn trong 12 tháng với những điều đặc biệt mà chỉ có tại IMIC và đây cũng chính là sự lựa chọn phù hợp nhất dành cho bạn:
👉 Thứ nhất: Học viên được đào tạo bài bản kỹ năng, kiến thức chuyên môn lý thuyết, thực hành, thực chiến nhiều dự án và chia sẻ những kinh nghiệm thực tế từ Chuyên gia có nhiều năm kinh nghiệm dự án cũng như tâm huyết truyền nghề.
👉 Thứ hai: Được ký hợp đồng cam kết chất lượng đào tạo cũng như mức lương sau tốt nghiệp và đi làm tại các đối tác tuyển dụng của IMIC. Trả lại học phí nếu không đúng những gì đã ký kết.
👉 Thứ ba: Cam kết hỗ trợ giới thiệu công việc sang đối tác tuyển dụng trong vòng 10 năm liên tục.
👉 Thứ tư: Được hỗ trợ tài chính với mức lãi suất 0 đồng qua ngân hàng VIB Bank.
👉 Có 4 Chương trình đào tạo nhân sự dài hạn dành cho bạn lựa chọn theo học. Gồm có:
1) Data Scientist full-stack
2) Embedded System & IoT development full-stack
3) Game development full-stack
4) Web development full-stack
✅ Cảm ơn bạn đã dành thời gian lắng nghe những chia sẻ của mình. Và tuyệt vời hơn nữa nếu IMIC được góp phần vào sự thành công của bạn.
✅ Hãy liên hệ ngay với Phòng tư vấn tuyển sinh để được hỗ trợ về thủ tục nhập học.
✅ Chúc bạn luôn có nhiều sức khỏe và thành công!