Chương II : Một Số Hàm Socket
7. Các phương thức đồng bộ(synchronized)
Đồng bộ hóa rất dể dàng trong Java vì các đối tượng đều có monitor đi kèm. Để truy xuất monitor của đối tượng chỉ cần gọi phương thức có thêm từ khóa synchronized. Trong khi một thread đang ở trong phương thức đồng bộ hóa, tất cả các thread khác đang chờ cố gắn gọi phương thức này. Để thoát khỏi monitor và từ bỏ điều khiển của một đối tượng để nhận tiểu trình kế tiếp đang chờ, monitor dừng phương thức đồng bộ.
Để hiểu sự cần thiết của việc đồng bộ hóa hãy bắt đầu với ví dụ đơn giản khơng cần đến việc đồng bộ này – nhưng việc đồng bộ sẽ sử dụng. Chương trình sau có 3 lớp đơn giản, lớp đầu tiên là Callme với phương thức call(). Phương thức call() nhận đối số msg kiểu String, sau đó in chuỗi msg trong dấu ngoặt vuông. Điều thú vị là sau khi call() in chuỗi msg nó gọi
Thread.sleep(1000) để ngưng thread hiện tại trong một giây.
Lớp kế tiếp là Caller với cấu tử nhận đối số tham chiếu đến lớp Callme và kiểu String. Cấu tử cũng tạo một thread mới thông qua phương thức run() và phương thức run() của lớp này gọi phương thức call() trên đối số msg của Callme. Sau cùng là lớp Synch khởi động bằng cách gọi của lớp Callme và ba cách gọi của lớp Caller với mỗi hàm gọi một chuỗi thông tin. Cùng
//This program is not sychronize. class Callme { void call(String msg) { System.out.print("[" + msg); try { Thread.sleep(1000); }catch(InterruptedException e) { System.out.print("interrupted"); } System.out.print("]"); } }
class Caller implements Runnable {
String msg; Callme target; Thread t;
public Caller(Callme targ,String s) { target=targ; msg=s; t=new Thread(this); t.start(); }
public void run() { target.call(msg); } } class Synch {
public static void main(String args[]) {
Callme target= new Callme();
Caller ob1= new Caller(target,"Hello");
7 Caller ob2= new Caller(target,"Synchronized"); Caller ob3= new Caller(target," World");
//wait for threads to end try { ob1.t.join(); ob2.t.join(); ob3.t.join(); }catch(InterruptedException e) {
System.out.println("Interrupted"); }
} }
Kết quả chương trình sau:
Starting application E:\BTJava\Synch.class
[Hello[Synchronized[ World]]]
Interactive Session Ended
Bằng cách gọi hàm sleep(), phương thức call() cho phép chuyển đổi thi hành qua lại giữa các thread. Kết quả trên xuất ra từ sự pha trộn ba chuổi thông điệp. Trong chương trình này, khơng có gì ngưng cả ba tiến trình từ việc gọi cùng phương thức trên cùng một đối tượng tại một thời điểm. Điều này xem như cùng điều kiện tốc độ vì ba thread chạy riêng lẻ.