Nội dung chính
Đồng bộ trong java
Đồng bộ trong java (Synchronization in java) là khả năng kiểm soát truy cập của nhiều luồng đến bất kỳ nguồn tài nguyên chia sẻ (shared resource).
Giả sử có nhiều luồng muốn truy cập cùng một biến cùng một thời điểm. Ví dụ một luồng muốn đọc, trong khi luồng khác cố gắng thay đổi dữ liệu dẫn dến dữ liệu bị sai lệch. Trong trường hợp này, Java Synchronization là lựa chọn tốt khi chúng ta muốn cho phép chỉ một luồng được truy cập vào tài nguyên chia sẻ đó.
Tại sao sử dụng Synchronization
Việc đồng bộ hóa chủ yếu được sử dụng để:
- Để tránh sự can thiệp của luồng khác.
- Để đảm bảo vấn đề nhất quán của chương trình.
Vấn đề xảy ra khi không sử dụng đồng bộ
Trong ví dụ này, không có sự đồng bộ, vì vậy đầu ra không phù hợp. Hãy xem ví dụ:
class Table { void printTable(int n) {// method không synchronized for (int i = 1; i <= 5; i++) { System.out.println(n * i); try { Thread.sleep(400); } catch (Exception e) { System.out.println(e); } } } } class MyThread1 extends Thread { Table t; MyThread1(Table t) { this.t = t; } public void run() { t.printTable(5); } } class MyThread2 extends Thread { Table t; MyThread2(Table t) { this.t = t; } public void run() { t.printTable(100); } } public class TestSynchronization1 { public static void main(String args[]) { Table obj = new Table();// tao mot object MyThread1 t1 = new MyThread1(obj); MyThread2 t2 = new MyThread2(obj); t1.start(); t2.start(); } }
Output:
5 100 200 10 300 15 400 20 25 500
Phương thức đồng bộ (synchronized method)
Nếu bạn khai báo bất kỳ phương pháp nào với từ khóa synchronized, nó được gọi là phương thức đồng bộ.
Phương thúc đồng bộ được sử dụng để khóa một đối tượng cho bất kỳ tài nguyên được chia sẻ.
Khi một luồng gọi một phương thức đồng bộ, nó sẽ tự động khóa cho đối tượng đó và giải phóng nó khi luồng hoàn thành nhiệm vụ.
Ví dụ về phương thức đồng bộ (synchronized method)
class Table { synchronized void printTable(int n) { // synchronized method for (int i = 1; i <= 5; i++) { System.out.println(n * i); try { Thread.sleep(400); } catch (Exception e) { System.out.println(e); } } } } class MyThread1 extends Thread { Table t; MyThread1(Table t) { this.t = t; } public void run() { t.printTable(5); } } class MyThread2 extends Thread { Table t; MyThread2(Table t) { this.t = t; } public void run() { t.printTable(100); } } public class TestSynchronization2 { public static void main(String args[]) { Table obj = new Table();// tao mot object MyThread1 t1 = new MyThread1(obj); MyThread2 t2 = new MyThread2(obj); t1.start(); t2.start(); } }
Output:
5 10 15 20 25 100 200 300 400 500
Ví dụ về synchronized method sử dụng lớp nặc danh
Trong chương trình sau đây, chúng ta đã tạo ra hai thread bằng lớp ẩn danh, do đó phải viết ít code hơn.
class Table { synchronized void printTable(int n) {// synchronized method for (int i = 1; i <= 5; i++) { System.out.println(n * i); try { Thread.sleep(400); } catch (Exception e) { System.out.println(e); } } } } public class TestSynchronization3 { public static void main(String args[]) { final Table obj = new Table();// tao mot object Thread t1 = new Thread() { public void run() { obj.printTable(5); } }; Thread t2 = new Thread() { public void run() { obj.printTable(100); } }; t1.start(); t2.start(); } }
Output:
5 10 15 20 25 100 200 300 400 500