Java Thread (Luồng trong Java)
Process và Thread là 2 thứ căn bản nhất trong thực thi. Lập trình đồng thời (concurrency programming) là một ví dụ điển hình về Thread.
Process
Process là nơi chứa đựng môi trường thực thi và có thể xem như là một chương trình hoặc là một ứng dụng. Một chương trình có thể chưa nhiều Process trong nó. JRE(Java Runtime Environment) chạy như là 1 process nơi mà chưa nhiều class và chương trình khác nhau.Thread
Thread còn được gọi là lightweight process. Thread không yêu cầu nhiều nguồn tài nguyên để tạo và tồn tại trong process. Thread chia sẻ nguồn tài nguyên của process.Mỗi ứng dụng Java đòi hỏi phải có ít nhất 1 Thread (main Thread). Mặt dù có nhiều loại thread chạy nền như là: bộ quản lý hệ thống, bô quản lý vùng nhớ, bộ xử lý tín hiệu. Nhưng theo góc nhìn ứng dụng, main là thread đầu tiên và chúng ta có thể tạo nhiều thread từ đó.
Multithreading(đa luồng) gồm có hai hoặc nhiều thread cùng thực thi trong một chương trình. Máy tính với 1 lõi (core) chỉ có thể thực thi một thread tại 1 thời gian và thời gian đó được chia nhỏ trong hệ điều hành để chia sẻ thời gian thực thi giữa các thread và process.
Lợi ích của Thread
- Thread khá nhẹ so với Process, và tốn ít thời, tài nguyên để khởi tạo 1 Thread.
- Thread chia sẽ dữ liệu và code của process cha.
- Sự chuyển đổi giữa các Thread tôn ít chi phí hơn so với Process.
- Sự giao tiếp giữa các Thread dễ dàng hơn so với Process.
Ta có 2 cách để tao Thread:
- Thực thi(implement) java.lang.Runnable interface.
- Thừa kế(extends) java.lang.Thread class.
Ví dụ về thực thi(implement) java.lang.Runnable interface.
Để tạo class runnable, chúng ta phải implement java.lang.Runnable interface và tiến hành thực thi(implementation) trong phương thức public void run(). Để sử dụng class như một Thread, chúng ta cần khởi tạo một đối tượng Thread bằng cách truyền class dưới đây vào Thread gọi hàm start() để thực thi hàmrun()
trong mỗi Thread.package com.journaldev.threads; public class HeavyWorkRunnable implements Runnable { @Override public void run() { System.out.println("Doing heavy processing - START "+Thread.currentThread().getName()); try { Thread.sleep(1000); //Get database connection, delete unused data from DB doDBProcessing(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Doing heavy processing - END "+Thread.currentThread().getName()); } private void doDBProcessing() throws InterruptedException { Thread.sleep(5000); } }
Ví dụ về Thừa kế(extends) java.lang.Thread class
Chúng ta có thể kế thừa java.lang.Thread class để tạo một class thread riêng và kế thừa hàm run(). Sau đó chúng ta tạo một object và gọi hàm start() để thực thi Thread class vừa mới tạo.package com.journaldev.threads; public class MyThread extends Thread { public MyThread(String name) { super(name); } @Override public void run() { System.out.println("MyThread - START "+Thread.currentThread().getName()); try { Thread.sleep(1000); //Get database connection, delete unused data from DB doDBProcessing(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("MyThread - END "+Thread.currentThread().getName()); } private void doDBProcessing() throws InterruptedException { Thread.sleep(5000); } }
Hàm main thực thi 2 ví dụ trên:
package com.journaldev.threads; public class ThreadRunExample { public static void main(String[] args){ Thread t1 = new Thread(new HeavyWorkRunnable(), "t1"); Thread t2 = new Thread(new HeavyWorkRunnable(), "t2"); System.out.println("Starting Runnable threads"); t1.start(); t2.start(); System.out.println("Runnable Threads has been started"); Thread t3 = new MyThread("t3"); Thread t4 = new MyThread("t4"); System.out.println("Starting MyThreads"); t3.start(); t4.start(); System.out.println("MyThreads has been started"); } }
Kết quả chương trình:
Starting Runnable threads Runnable Threads has been started Doing heavy processing - START t1 Doing heavy processing - START t2 Starting MyThreads MyThread - START Thread-0 MyThreads has been started MyThread - START Thread-1 Doing heavy processing - END t2 MyThread - END Thread-1 MyThread - END Thread-0 Doing heavy processing - END t1
Khi chúng ta khởi động thread, nó sẽ thực thi dựa theo hệ điều hành thực thi với thời gian chia nhỏ cho mỗi thread, chúng ta không thể điều khiển vấn đề này. Tuy nhiên chúng ta có thể xét độ ưu tiên, nhưng điều này không đảm bảo những thread có độ ưu tiên cao sẽ được thực thi trước.
Chạy chương trình trên nhiều lần bạn sẽ thấy mỗi lần chạy sẽ xuất ra kết quả khác nhau, không có qui luật cụ thể.
Runnable và Thread
Nếu class của bạn thiên về chức năng hơn là chạy Thread, bạn nên implement Runnable interface. Nếu mục đích class của bạn là để chạy như Thread, thì bạn có thể extends(thừa kế)Thread.Thực thi(Implement) Runnable đựa ưu tiên hơn vì java có thể thực thi(implememt) nhiều interface. Nếu bạn thừa kế(extends) class, thì bạn không thể thừa kế bất ký class nào khác.
Mẹo:Như bạn đã thấy Thread không trả về(return) bất kỳ giá trị nào, nhưng nếu bạn muốn class xử lý một vài chức năng sau đó trả về(return) giá trị. Chúng ta sẽ tham khảo bài viết kế tiếp.
Ghi Chú: Từ java 8 trở đi ta có thể sử dụng lambda expression để thực thi (implement) hơn là sử dụng class ẩn danh(anonymous)
Nguồn: Java Thread example
0 comments:
Post a Comment