Chào bạn, hôm nay mình sẽ giới thiệu cho bạn một kiến thức rất hay đó là đa luồng và cách để lập trình đa luồng trong Java.
Lập trình đa luồng trong Java
Nội dung của bài viết này gồm:
-
Vòng đời của đa luồng trong Java
-
Cách tạo luồng trong Java
-
Ví dụ về lập trình đa luồng trong Java.
1. Đa luồng là gì?
Trước hết chúng ta phải hiểu luồng (Thread) là gì?
Luồng ở đây chính là luồng xử lý của hệ thống.
Về cơ bản thì nó là một tiến trình con (sub process), một đơn vị nhỏ nhất của máy tính có thể thực hiện một công việc riêng biệt.
Một ứng dụng có thể được chia nhỏ thành nhiều nhiệm vụ và mỗi nhiệm vụ có thể được giao cho một thread.
Biết cách lập trình đa luồng là một yêu cầu bắt buộc tận dụng được sức mạnh thật sự của Java, việc học Java của bạn sẽ tiến một bước gần hơn đến việc thực sự có thể làm ra các ứng dụng Java hoàn chỉnh.
> Nếu bạn muốn học Java để đi làm thì xem ngay KHÓA HỌC JAVA (Full stack) với chuyên gia doanh nghiệp.
Minh họa Luồng trong Java
Trong Java, các luồng được quản lý bởi máy ảo Java (JVM).
Đa luồng – Multi Thread là một tiến trình thực hiện nhiều luồng đồng thời.
Trong một chương trình, ngoài luồng chính thì 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.
Theo như những gì chúng ta làm từ trước đến giờ, thì code của chúng ta sẽ được hệ thống xử lý một cách tuần tự từ trên xuống dưới.
Giả sử chương trình của chúng ta chia ra làm 3 phần A, B, C và chương trình sẽ chạy lần lượt từ A, rồi đến B, và cuối cùng là C.
Nhưng sau bài viết này, chúng ta sẽ tổ chức sao cho A, B, C là 3 thread độc lập nhau và hệ thống sẽ xử lý 3 thread này một cách đồng thời.
Một ví dụ đơn giản về đa luồng đó chính là trình phát nhạc trên điện thoại của bạn.
Khi bạn đang nghe một bài hát, bạn thấy hay và bạn muồn tải nó về, thì quá trình tải bài hát đó sẽ được chạy trên một thread riêng, quá trình phát nhạc được chạy trên một thread riêng nữa, vì vậy bạn vừa có thể nghe nhạc đồng thời có thể tải bài hát đó về máy.
Ưu điểm của đa luồng:
-
Nó không chặn người sử dụng vì các luồng là độc lập và bạn có thể thực hiện nhiều thao tác cùng một lúc.
-
Chính vì thao tác được nhiều công việc cùng lúc nên sẽ tiết kiệm được thời gian.
-
Vì các luồng là độc lập, do đó khi có một exception xảy ra trong một luồng nào đó thì nó cũng sẽ không ảnh hưởng tới luồng khác.
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 và tránh các dead lock, luồng chạy mà không làm gì trong ứng dụng cả.
2. Vòng đời của luồng (Thread) trong java
Một thread trải qua các giai đoạn khác nhau trong vòng đời của nó. Dưới đây là vòng đời hoàn chỉnh của một thread.
Vòng đời của luồng trong Java
Để hiểu rõ hơn các thread, chúng ta sẽ tìm hiểu thread ở trong 5 trạng thái:
-
New: Một thread bắt đầu một vòng đời của nó trong trạng thái new. Nó vẫn ở trạng thái này cho tới khi chương trình gọi phương thức start() để bắt đầu thread. Ở 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.
-
Runnable: Thread ở trạng thái runnable sau khi gọi phương thức start(), lúc này luồng đã được cấp phát tài nguyên. Một thread trong trạng thái được thực hiện nhiệm vụ của nó.
-
Waiting: Đôi khi một luồng chuyển sang trạng thái waiting trong lúc chờ một luồng khác thực hiện một tác vụ. Thread chờ cho đến khi một luồng khác đánh thức nó.
-
Timed Waiting: Thread chờ trong một thời gian nhất định, hoặc là có một luồng khác đánh thức nó.
-
Terminated (Dead): Một thread ở trong trạng thái terminated hoặc dead khi phương thức run() của nó bị thoát.
3. Cách tạo luồng trong Java
Trong Java có hai cách tạo luồng chính đó là extend từ class Thread hoặc implements từ interface Runnable.
Cách #1: Tạo luồng bằng cách extend từ class Thread
Để tạo luồng theo cách này bạn thực hiện theo các bước sau:
-
Bước 1: Khai báo một class kế thừa từ class
Thread
-
Bước 2: Override lại phương thức
run()
của class Thread. Mọi thứ sẽ được thực thi trong run()
khi luồng bắt đầu chạy. Khi luồng chạy xong thì những gì trong phương thức run()
này cũng sẽ bị hủy.
-
Bước 3: Tạo một đối tượng của lớp ta vừa khai báo, sau đó
start()
đối tượng vừa khai báo để bắt đầu chạy luồng.
Sau đây là một ví dụ cụ thể tạo luồng bằng cách extends từ class Thread:
public class ThreadDemo extends Thread{
@Override
public void run() {
super.run();
System.out.println("Hello world");
}
public static void main(String[] args) {
ThreadDemo thread1 = new ThreadDemo();
thread1.start();
}
}
Như vậy, thread1
chạy hoàn toàn trong 1 luồng riêng biệt và không chặn các luồng khác.
Cách #2: Tạo luồng bằng cách implement interface runnable
-
Bước 1: Khai báo một class sau đó implement interface runnable
-
Bước 2: Override lại phương thức
run()
. Mọi thứ sẽ được thực thi trong run()
khi luồng bắt đầu chạy. Khi luồng chạy xong thì những gì trong phương thức run()
này cũng sẽ bị hủy. (Giống cách 1)
-
Bước 3: Tạo một đối tượng của lớp ta vừa khai báo. Sau đó tạo một đối tượng lớp Thread bằng phương thức khởi tạo rồi truyền vào tham số Runnable, sau đó
start()
đối tượng vừa khai báo để bắt đầu chạy luồng.
Ví dụ:
public class RunnableDemo implements Runnable{
@Override
public void run() {
System.out.println("Hello world");
}
public static void main(String[] args) {
RunnableDemo runnable = new RunnableDemo();
Thread thread = new Thread(runnable);
thread.start();
}
}
4. Ví dụ về lập trình đa luồng trong java
Ở trong ví dụ này, mình sử dụng cách tạo luồng bằng cách extend class Thread nha…
Mình có class ThreadDemo:
public class ThreadDemo extends Thread{
private Thread t;
private String threadName;
ThreadDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Để thread ngủ một lúc.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start() {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start();
}
}
}
Tiếp theo, mình tạo class TestThread:
Sau đó mình tạo 2 luồng T1 và T1 và cho chúng chạy.
public class TestThread {
public static void main(String[] args) {
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
ThreadDemo T2 = new ThreadDemo( "Thread-2");
T2.start();
}
}
Kết quả chạy code:
Kết quả của ví dụ lập trình đa luồng trong Java
Như bạn thấy, chương trình bắt đầu tạo thread 1 và thread 2 và cho chúng chạy đồng thời với nhau chứ không đợi luồng kết thúc rồi mới chạy luồng thứ 2.
Bằng cách này, bạn có thể tận dụng sức mạnh của máy tính để có thể thực thi nhiều luồng nhằm tăng tốc độ và hiệu suất xử lý.
Tạm kết
Vậy là mình cùng các bạn vừa tìm hiểu xong các kiến thức cơ bản nhất về thread trong Java.
Thông qua bài viết này bạn sẽ hiểu được khái niệm về thread, multi thread, các cách tạo thread trong Java và lập trình đa luồng với Java.
Hẹn gặp lại các bạn ở các bài viết tiếp theo.
> Đọc thêm: Try catch trong Java
---
HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI
Học Lập trình chất lượng cao (Since 2002). Học làm Lập trình viên. Hành động ngay!
Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội
SĐT: 02435574074 - 0914939543 - 0353655150
Email: hello@niithanoi.edu.vn
Fanpage: https://facebook.com/NIIT.ICT/
#niit #niithanoi #niiticthanoi #hoclaptrinh #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp #java #php #python