Concurrency in Java phần 1

Chào mọi người mình có sẽ viết một chuỗi các bài về sử lý đa luồng trong java. Sau đây sẽ là bài đầu tiên của mình. Hy vọng mọi người ủng hộ để mình có động lực cho ra bài tiếp theo.

Synchronize

1. Chia sẻ biến trong các luồng

- Bạn mong đợi đoạn code sau sẽ kết thúc sau bao nhiêu giây?

 import java.util.concurrent.TimeUnit; public class Synchronize { private static boolean stopRequested; public static void stopThread() throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Overridepublic void run() { int i =0; while (!stopRequested){ i++; } } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; } public static void main(String[] args) throws InterruptedException { stopThread(); } }
- Có phải bạn mong đợi nó sẽ chạy trong khoảng hơn 1s ,sau khi biến stopRequested = true sẽ break vòng lặp while. Nhưng sự thật không phải như vậy vòng lặp sẽ là vô tận. Vì sao vậy chúng ta sẽ tìm hiểu thêm về Synchronize trong bài viết này. Câu trả lời sẽ nằm đâu đó trong bài viết.Từ khóa synchronized

- Từ khóa synchronized đảm bảo chỉ có duy nhất một luồng có thể chạy một khối lệnh tại một thơi điểm.- Nhiều lập trình viên nghĩ đồng bộ hóa chỉ giải quyết bài toán loại trừ lẫn nhau. Cách nhìn nhận này là đúng nhưng vẫn chỉ là một nửa của câu chuyện. Nếu không có đồng bộ hóa khi một luồng thay đổi nó sẽ không được nhìn được từ một luồng khác nó. Đồng bộ hóa là cần thiết để giao tiếp giữa các luồng.

Vậy vấn đề ở trên là gì?

- Do sự thiếu sự đồng bộ hóa nên không có gì đảm bảo rằng backgroundThread sẽ nhìn thấy biến stopRequested đã được thay đổi.


Cách giải quyết.

1. Đồng bộ hóa quyền truy cập biến stopRequested

-Một cách để khắc phục sự cố là đồng bộ hóa quyền truy cập vào biến stopRequested. Chương trình này kết thúc sau khoảng một giây, như mong đợi:

import java.util.concurrent.TimeUnit; public class Synchronize { private static boolean stopRequested; private static synchronized void requestStop() { stopRequested = true; } private static synchronized boolean stopRequested() { return stopRequested; } public static void stopThread() throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Overridepublic void run() { int i =0; while (!stopRequested()){ i++; } } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); requestStop(); } public static void main(String[] args) throws InterruptedException { stopThread(); } }
2. Sử dụng từ khóa volatile- volatile không sử dụng trong loại trừ lẫn nhau như từ khóa synchronized nhưng nó đảm bảo rằng bất cứ luồng nào sử dụng các biến sẽ nhìn thấy được giá trị gần nhất của nó. Ta sẽ thay đổi code như sau.

import java.util.concurrent.TimeUnit; public class Synchronize { private static volatile boolean stopRequested; public static void stopThread() throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Overridepublic void run() { int i =0; while (!stopRequested){ i++; } } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; } public static void main(String[] args) throws InterruptedException { stopThread(); } }
Cách sử dụng từ khóa synchronized để giải quyết bài toán loại trừ lẫn nhau mình thấy trên mạng đã có rất nhiều bài viết tiếng việt nên mình không đề cập chức năng này của đồng bộ hóa nữa.Bài viết về chia sẻ biến trên các luồng đến đây là kết thúc. Cảm ơn mọi người đã xem đến đây. Mình sẽ ra phần tiếp theo liên quan đến chủ đề Concurrency. Xin chào và không hẹn gặp lại.

Từ khóa: vtcc_intern_4, java, concurrency, Công nghệ thông tin