!
%
(
$
+
%
%
)
%
Sự không thuận lợi của các phương thức đồng bộ
Người lập trình thường viết các chương trình trên các đơn thể luồng. Tất nhiên các
trạng thái này chắc chắn không lợi ích cho đa luồng. Lấy ví dụ, lụồng không tận dụng việc
thực thi của trình biên dịch. Trình biên dịch Java từ Sun không chứa nhiều phương thức
đồng bộ.
Các phương thức đồng bộ không thực thi tốt như là các phương thức không đồng
bộ. Các phương thức này chậm hơn từ ba đến bốn lần so với các phương thức tương ứng
không đồng bộ. Trong trạng thái nơi mà việc thực thi là có giới hạn, các phương thức đồng
bộ bị ngăn ngừa.
8.11 Kỹ thuật “wait-notify” (đợi – thông báo)
Luồng chia các tác vụ thành các đơn vị riêng biệt và logic (hợp lý). Điều này thay
thế các trường hợp (sự kiện) chương trình lặp. Các luồng loại trừ “polling” (kiểm soát
vòng).
Một vòng lặp mà lặp lại việc một số điều kiện thường thực thi “polling” (kiểm soát
vòng). Khi điều kiện nhận giá trị là True (đúng), các câu lệnh phúc đáp được thực hiện.
Đây là tiến trình thường bỏ phí thời gian của CPU. Lấy ví dụ, khi một luồng sinh ra một số
dữ liệu, và các luồng khác đang chi phối nó, luồng sinh ra phải đợi cho đến khi các luồng
sử dụng nó hoàn thành, trước khi phát sinh ra dữ liệu.
Để tránh trường hợp kiểm soát vòng, Java bao gồm một thiết kế tốt trong tiến trình
kỹ thuật truyền thông sử dụng các phương thức “wait()” (đợi), “notify()” (thông báo) và
“notifyAll()” (thông báo hết). Các phương thức này được thực hiện như là các các phương
thức cuối cùng trong lớp đối tượng (Object), để mà tất cả các lớp có thể thâm nhập
chúng. Tất cả 3 phương thức này có thể được gọi chỉ từ trong phạm vi một phương thức
đồng bộ (synchronized).
Các chức năng của các phương thức “wait()”, “notify()”, và “notifyAll()” là:
Phương thức wait() nói cho việc gọi luồng trao cho monitor (sự giám sát), và
nhập trạng thái “sleep” (chờ) cho đến khi một số luồng khác thâm nhập cùng
monitor, và gọi phương thức “notify()”.
Phương thức notify() đánh thức, hoặc thông báo cho luồng đầu tiên mà đã gọi
phương thức wait() trên cùng đối tượng.
Phương thức notifyAll() đánh thức, hoặc thông báo tất cả các luồng mà đã gọi
phương thức wait() trên cùng đối tượng.
Quyền ưu tiên cao nhất luồng chạy đầu tiên.
Cú pháp của 3 phương thức này như sau:
final void wait() throws IOException
final void notify()
final void notifyAll()
Các phương thức wait() và notify() cho phép một đối tượng được chia sẻ để tạm
ngừng một luồng, khi đối tượng trở thành không còn giá trị cho luồng. Chúng cũng cho
phép luồng tiếp tục khi thích hợp.
Các luồng bản thân nó không bao giờ kiểm tra trạng thái của đối tượng đã chia sẻ.
Một đối tượng mà điều khiển các luồng khách (client) của chính nó theo kiểu này
được biết như là một monitor (sự giám sát). Trong các thuật ngữ chặt chẽ của Java, một
monitor là bất kỳ đối tượng nào mà có một số mã đồng bộ. Các monitor được sử dụng cho
các phương thức wait() và notify(). Cả hai phương thức này phải được gọi trong mã đồng