4 cách viết code đa luồng trong Java

Đa luồng là một phương pháp viết code để thực thi nhiều tác vụ song song. Java hỗ trợ tuyệt vời cho viết code đa luồng ngay từ phiên bản Java 1.0. Những cải tiến mới đây trong Java đã tăng số cách mà code được cấu trúc hóa để kết hợp nhiều luồng trong các chương trình Java. Trong bài viết này, Quantrimang.com so sánh một vài lựa chọn để viết code đa luồng, hy vọng bạn đọc có thể chọn được cho mình một cách phù hợp để áp dụng trong dự án Java tiếp theo của mình.
4 cách viết code đa luồng trong Java

Cách 1: Mở rộng lớp Thread

Java cung cấp lớp Thread có thể mở rộng để thực hiện run(). run() chính là nơi để thực thi tác vụ. Khi bạn muốn khởi động một tác vụ trong thread riêng của nó, có thể tạo instance trong class này và gọi start(). Điều này sẽ bắt đầu thực hiện thread và chạy để hoàn thành (hoặc chấm dứt) tác vụ.
Đây là một lớp Thread đơn giản thực hiện tác vụ ngủ trong một khoảng thời gian xác định như là một cách để mô phỏng một hoạt động chạy trong thời gian dài.
public class MyThread extends Thread { private int sleepFor; public MyThread(int sleepFor) { this.sleepFor = sleepFor; } @Override public void run() { System.out.printf('[%s] thread startingn', Thread.currentThread().toString()); try { Thread.sleep(this.sleepFor); } catch(InterruptedException ex) {} System.out.printf('[%s] thread endingn', Thread.currentThread().toString()); } }[/code] Tạo instance của lớp Thread này bằng cách đưa cho nó số mili giây để ngủ.
MyThread worker = new MyThread(sleepFor);[/code] Khởi chạy tiến trình của luồng worker trên bằng cách gọi phương thức start() của nó. Phương thức này sẽ trả về control ngay lập tức cho caller mà không cần đợi luồng chấm dứt.
worker.start(); System.out.printf('[%s] main threadn', Thread.currentThread().toString());[/code] Và đây là đầu ra khi chạy code này. Nó chỉ ra rằng thread chính được in trước khi luồng worker hoàn thành.
[Thread[main,5,main]] main thread [Thread[Thread-0,5,main]] thread starting [Thread[Thread-0,5,main]] thread ending[/code] Bởi vì không có lệnh nào sau khi bắt đầu luồng worker, luồng chính sẽ đợi cho luồng worker kết thúc trước khi chương trình thoát. Điều này cho phép luồng worker hoàn thành hết các tác vụ của mình.

Cách 2: Sử dụng Thread Instance với Runnable

Java cũng cung cấp một giao diện gọi là Runnable, có thể được thực hiện bởi một lớp worker để thực thi tác vụ trong phương thức run() của nó. Đây là một cách khác để tạo lớp worker thay vì mở rộng lớp Thread (được mô tả bên trên).
Đây là cách thực hiện lớp worker với Runnable thay vì mở rộng Thread. Ưu điểm của cách này lớp worker có thể mở rộng một lớp cụ thể theo miền trong một phân cấp lớp (class hierarchy). Điều đó có nghĩa là gì? Ví dụ, bạn có lớp Fruit chứa những đặc điểm chung thuộc về trái cây. Bây giờ bạn muốn thực hiện một lớp Papaya với những đặc điểm nào đó của trái cây. Bạn có thể làm điều đó bằng code sau:
public class Fruit { // fruit specifics here } public class Papaya extends Fruit { // override behavior specific to papaya here }[/code] Bây giờ, giả sử có một số tác vụ tốn thời gian mà Papaya cần hỗ trợ, có thể được thực hiện trong một luồng riêng biệt. Trường hợp này có thể được xử lý bằng cách yêu cầu lớp Papaya thực thi Runnable và cung cấp phương thức run() nơi mà nhiệm vụ này được thực hiện.
public class Papaya extends Fruit implements Runnable { // override behavior specific to papaya here @Override public void run() { // time consuming task here. } }[/code] Để khởi động luồng worker, tạo một instance của lớp worker và giao nó cho instance Thread trong quá trình tạo. Khi phương thức start() của Thread được gọi, nhiệm vụ sẽ thực hiện trong một luồng riêng biệt.
Papaya papaya = new Papaya(); // set properties and invoke papaya methods here. Thread thread = new Thread(papaya); thread.start();[/code] Và đó là cách đơn giản để sử dụng Runnable thực hiện tác vụ trong một luồng.

Cách 3: Triển khai Runnable với ExecutorService

Bắt đầu từ phiên bản 1.5, Java có thêm ExecutorService như một mô hình mới để tạo và quản lý các luồng trong một chương trình. Nó tổng quát khái niệm về việc triển khai luồng bằng cách trừu tượng hóa việc tạo các luồng. Điều này là do bạn có thể chạy nhiều tác vụ trong nhóm luồng, sử dụng luồng riêng biệt cho mỗi tác vụ. Nhờ đó, chương trình có thể theo dõi và quản lý xem có bao nhiêu luồng được sử dụng cho các tác vụ worker.
Giả sử bạn có 100 tác vụ worker đang chờ để thực hiện. Nếu bắt đầu một luồng cho mỗi worker thì sẽ có 100 luồng trong chương trình. Điều này có thể dẫn tới tình trạng thắt nút cổ chai ở những nơi khác trong chương trình. Thay vào đó, nếu sử dụng nhóm luồng, 10 luồng được phân bổ trước, 100 tác vụ sẽ được thực thi bởi những luồng này, lần lượt từng nhóm một, và chương trình sẽ không bị thiếu tài nguyên. Ngoài ra, nhóm luồng này có thể được cấu hình để thực hiện thêm những nhiệm vụ bổ sung.  ExecutorService chấp nhận một tác vụ Runnable và chạy tác vụ vào một thời điểm thích hợp. Phương thức submit() trả về instance cảu một lớp được gọi là Future, cho phép caller theo dõi trạng thái của tác vụ. Cụ thể, phương thức get() cho phép caller đợi cho đến khi tác vụ hoàn thành (và cung cấp code trả về, nếu có). Trong ví dụ dưới đây, chúng ta có thể tạo ExecutorService sử dụng phương thức tĩnh newSingleThreadExecutor(), nhằm tạo một luồng đơn để thực hiện các tác vụ. Nếu có nhiều tác vụ được submit trong khi một tác vụ khác đang chạy thì ExcecutorService sẽ sắp xếp những tác vụ này để thực thi tiếp theo, sau khi tác vụ trước kết thúc. Đây là ví dụ cho mô tả dài loằng ngoằng ở trên:
ExecutorService esvc = Executors.newSingleThreadExecutor(); Runnable worker = new MyThread2(sleepFor); Future<?> future = esvc.submit(worker); System.out.printf('[%s] main threadn', Thread.currentThread().toString()); future.get(); esvc.shutdown();[/code] Lưu ý rằng, ExecutorService phải được đóng lại đúng cách khi không cần dùng đến nó để submit các tác vụ tiếp theo.

Cách 4: Sử dụng Callable với ExecutorService

Trong phiên bản 1.5 Java giới thiệu Callable mới, khá giống với Runnable. Khác biệt là phương thức thưc hiện (được gọi là call() thay vì run()) có thể trả về một giá trị. Nó cũng có thể khai báo một Exception được đưa vào. ExecutorService có thể chấp nhận các tác vụ được thực hiện như Callable và trả về Future với giá trị được trả về bởi phương thức khi kết thúc tác vụ.
Đây là ví dụ về lớp Mango, mở rộng lớp Fruit được định nghĩa trước đó và thực hiện Callable. Một tác vụ nặng và tốn nhiều thời gian sẽ được thực hiện trong call().
public class Mango extends Fruit implements Callable { public Integer call() { // expensive computation here return new Integer(0); } }[/code] Và đây là code để submit môt instance của lớp vào ExcecutorService. Đoạn code bên dưới cũng đợi đến khi tác vụ hoàn thành và in giá trị nó trả về.
ExecutorService esvc = Executors.newSingleThreadExecutor(); MyCallable worker = new MyCallable(sleepFor); Future future = esvc.submit(worker); System.out.printf('[%s] main threadn', Thread.currentThread().toString()); System.out.println('Task returned: ' + future.get()); esvc.shutdown();[/code]

Bạn thích cách tạo thread nào hơn?

Trong bài này, chúng ta có phương pháp để viết code đa luồng trong Java.
Hy vọng bài viết có thể giúp bạn một phần nào đó!
Nguồn: https://quantrimang.com/4-cach-viet-code-da-luong-trong-java-137931 

TIN LIÊN QUAN

Hướng dẫn cài đặt Oracle Java trên Ubuntu Linux

Nếu đã cài đặt Oracle Java 7 trên hệ điều hành nhưng muốn nâng cấp, hãy tham khảo bài hướng dẫn nâng cấp Oracle Java trên Ubuntu Linux. Với những người chỉ muốn cài đặt Oracle Java JRE để chạy ứng dụng Java chứ không phát triển chương trình Java,

Hướng dẫn cách mở và chạy tập tin JAR khả thi

Tương tự, đa số tệp JAR khả thi được tải về như một file cài đặt với mục đích cài đặt ứng dụng hay chương trình. Do đó, nếu gặp vấn đề trong việc mở file, bạn nên kiểm tra lại xem tệp JAR của bạn có tương thích với hệ điều hành hay không.

Hướng dẫn cách cài đặt Java cho máy tính

Chúng ta có thể thấy rõ nhất vai trò của Java khi chơi các game dạng như Minecraft và lỗi Java trên Minecraft là một trong những lỗi cực kỳ phổ biến. Vì vậy, việc cài Java lên máy tính cũng là một cách sửa lỗi Java trên Minecraft .

Lý do khiến ngôn ngữ lập trình C không bao giờ lỗi thời

Tạp chí IEEE Spectrum xếp ngôn ngữ C như là ngôn ngữ hàng đầu trong năm 2017 trước cả Java, C # và jаvascript. Nếu bạn học C trong năm nay, nó sẽ không làm lãng phí thời gian và công sức của bạn. Dưới đây là năm lý do tại sao.

Những vấn đề cần nắm bắt khi bắt đầu học lập trình máy tính

Lập trình thật vui và vô cùng hữu dụng. Với lập trình, bạn sẽ được thỏa sức sáng tạo cùng nhiều cơ hội việc làm rộng mở. Nếu muốn học cách lập trình, hãy đọc chỉ dẫn dưới đây để nắm được nơi bạn cần đi và những gì mà bạn cần học.

Những điều cần làm ngay lập tức khi diệt xong Virus

Nếu máy vi tính của bạn bị nhiễm virus hoặc các loại mã độc khác, quét virus mới chỉ là bước đầu tiên. Bạn cần thực hiện thêm nhiều bước để đảm bảo rằng máy vi tính của bạn luôn được đảm bảo an toàn.

Apple phát hành công cụ gỡ bỏ Flashback

Apple vừa phát hành công cụ mới để loại bỏ Flashback, phần mềm giả mạo dùng để ăn cắp thông tin người dùng.

THỦ THUẬT HAY

Cách tải FO4 online siêu cấp miễn phí nhanh nhất 2023

FIFA Online 4 hay còn được viết tắt là FO4 là game thể thao bóng đá ăn khách nhất thị trường game. Có nhiều đổi mới phiên bản này khi so sánh với các phần trước của series. Người ta đã chú trọng hơn vào việc thay đổi

Hướng dẫn sử dụng Apple Pencil trên iPhone và các máy iPad không được hỗ trợ

Theo đó, bạn đọc chỉ cần cuốn một lớp khăn giấy hơi ướt xung quanh Apple Pencil như trong video. Sau khi thực hiện xong, bạn có thể viết và vẽ hết sức bình thường trên chiếc iPhone của mình.

Hướng dẫn tải và cài đặt Foxit Reader để đọc file PDF

Ngoài sự tiện lợi như trên, văn bản PDF có những ưu điểm khác là khiến người dùng cảm thấy yên tâm với độ bảo mật cao, không dễ dàng bị cài cắm mã độc.., chính vì vậy, những định dạng văn bản này đang ngày càng trở nên

Kiểm tra hiệu năng máy tính với SiSoftware Sandra

SiSoftware Sandra là một công cụ kiểm tra thông tin hệ thống phổ biến nhưng nó cũng bao gồm các tiện ích kiểm tra hiệu năng máy tính. Hãy xem bài viết này để biết cách sử dụng nó kiểm tra hiệu suất máy tính của bạn nhé!

Image Transfer – Chuyển nhanh hình ảnh và video giữa iPhone và máy tính không cần cắm dây

Giải pháp mới trong việc chuyển hình ảnh và video giữa iPhone với iPhone và máy tính.

ĐÁNH GIÁ NHANH

Mở hộp Sony XPERIA L1 Dual: Màn hình 5.5 inches, camera 13 MP, nổi bật trong phân khúc giá 4.490.000 đồng

Sau khi chính thức ra mắt tại Việt Nam, Sony XPERIA L1 Dual nhanh chóng trở thu hút sự quan tâm của nhiều người với mức giá dưới 5 triệu đồng. Đây hứa hẹn là một sản phẩm sẽ tạo nên làn sóng trong phân khúc giá này.

Đánh giá Xiaomi Redmi EarBuds 3 Pro: Tai nghe sở hữu chip Qualcomm xịn sò, thời lượng pin lên tới 30 tiếng, giá chưa đến 1 triệu đồng

Vừa qua, Xiaomi đã chính thức trình làng mẫu tai nghe không dây mới nhất có tên gọi Redmi EarBuds 3 Pro. Sản phẩm không chỉ sở hữu vẻ ngoài trẻ trung với nhiều tùy chọn màu cá tính, mà nó còn được trang bị nhiều tính

Đánh giá Samsung Galaxy A8/A8+: Có những tính năng gì hấp dẫn?

Bộ đôi Samsung Galaxy A8 và Galaxy A8+ phiên bản 2018 có nhiều nâng cấp tới mức chúng ta đã quên đi chiếc Galaxy A8 trước đây. Đơn giản vì Samsung đã gần như “lột xác” hoàn toàn dòng Galaxy A của họ. Do đó khi nhắc đến