Recent Posts

Lập Trình Đa Luồng (Multithreading) Demo producer and consumer in Java

-

 Đa luồng trong java (Multithreading in 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<String> {
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
/**
*
* @author HAINN
*/
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
/**
*
* @author HAINN
*/
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
/**
*
* @author HAINN
*/
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
/**
*
* @author HAINN
*/
public class Main {

/**
* @param args the command line arguments
*/
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();
}
}


Related Post:

  • Mật mã học: Tổng quan về mật mã họcMật mã học là gì Mật mã học là một lĩnh vực liên quan với các kỹ thuật ngôn ngữ và toán học để đảm bảo an toàn thông tin, cụ thể là trong thông tin liên lạc. Về phương diện lịch sử, mật mã học gắn liền với quá trình mã hóa; điều này có nghĩa là nó gắn với các cách thức để chuyển đổi thông tin từ dạng này sang dạng khác nhưng ở đây là từ dạng thông thường có thể n… Read More
  • Mật mã học: Mật mã hóa KHÓA CÔNG KHAI (Khóa bất đối xứng)Mật mã hóa khóa công khai là một dạng mật mã hóa cho phép người sử dụng trao đổi các thông tin mật mà không cần phải trao đổi các khóa chung bí mật trước đó. Điều này được thực hiện bằng cách sử dụng một cặp khóa có quan hệ toán học với nhau là khóa công khai và khóa cá nhân (hay khóa bí mật).Thuật ngữ mật mã hóa khóa bất đối xứng thường được dùng đồng nghĩa với mật m… Read More
  • Mật mã học: Mật mã Caesar (Mã hóa Caesar)Trong mật mã học, mật mã Caesar, còn gọi là mật mã dịch chuyển, là một trong những mật mã đơn giản và được biết đến nhiều nhất. Mật mã là một dạng của mật mã thay thế, trong đó mỗi ký tự trong văn bản được thay thế bằng một ký tự cách nó một đoạn trong bảng chữ cái để tạo thành bản mã. Vĩ dụ, nếu độ dịch là 3, A sẽ được thay bằng B, Ă sẽ được thay bằng C và cứ thế đến… Read More
  • HTML: Tổng quan về JavaScript1. GIỚI THIỆU VỀ JAVASCRIPT: Javascript ra đời với tên gọi LiveScript, sau đó Nescape đổi tên thành Javascript. Tuy nhiên giữa Java và Javascript có rất ít các điểm chung dù cú pháp của chúng có thể có những điểm giống nhau.Javascript là một ngôn ngữ kịch bản (script) để viết kịch bản cho phía client. Client side là những yêu cầu của người sử dụng được xử lý tại … Read More
  • JavaScript: Khai báo và sử dụng hàm trong JavaScript1. ĐỊNH NGHĨAHàm là một đọan chương trình có thể được sử dụng nhiều lần trong một chương trình để thực hiện một tác vụ nào đó.1.1. Xây dựng hàm: Trong JavaScript, dùng từ khoá function để định nghĩa hàm. Một hàm có cấu trúc như sau:- NameFunction: là tên hàm do người lập trình tự đặt. - Qui tắc đặt tên hàm giống như tên biến. Sau NameFunction là cặp dấu ngoặc ( )… Read More
  • Mật mã học: Thuật toán khóa đối xứng (Symmetric-Key Algorithms)Trong mật mã học, các thuật toán khóa đối xứng (tiếng Anh: symmetric-key algorithms) là một lớp các thuật toán mật mã hóa trong đó các khóa dùng cho việc mật mã hóa và giải mã có quan hệ rõ ràng với nhau (có thể dễ dàng tìm được một khóa nếu biết khóa kia).Khóa dùng để mã hóa có liên hệ một cách rõ ràng với khóa dùng để giải mã có nghĩa chúng có thể hoàn toàn giống nh… Read More




Klik untuk melihat kode: :) =( :s :D :-D ^:D ^o^ 7:( :Q :p T_T @@, :-a :W *fck* x@