2010-02-16 66 views
6

Dưới đây là mã trực tiếp từ hướng dẫn của Sun mô tả Deadlock. Tuy nhiên tôi không hiểu làm thế nào Deadlock có thể xảy ra trong tình huống này xem xét cả hai phương pháp được đồng bộ hóa. Hai Thread sẽ nằm trong cùng một phương thức đồng bộ cùng một lúc như thế nào?Câu hỏi về Deadlock từ hướng dẫn Sun

Khóa chết mô tả tình huống có hai hoặc nhiều chuỗi bị chặn vĩnh viễn, chờ đợi nhau. Đây là một ví dụ.

Alphonse và Gaston là bạn bè và những người tin tưởng tuyệt vời trong lịch sự. Một quy tắc lịch sự nghiêm ngặt là khi bạn cúi đầu chào một người bạn, bạn phải cúi chào cho đến khi bạn của bạn có cơ hội trả lại cây cung. Thật không may, quy tắc này không tính đến khả năng hai người bạn có thể cúi đầu với nhau cùng một lúc. Ứng dụng ví dụ này, Deadlock, mô hình khả năng này:

public class Deadlock { 
    static class Friend { 
     private final String name; 
     public Friend(String name) { 
      this.name = name; 
     } 
     public String getName() { 
      return this.name; 
     } 
     public synchronized void bow(Friend bower) { 
      System.out.format("%s: %s has bowed to me!%n", 
        this.name, bower.getName()); 
      bower.bowBack(this); 
     } 
     public synchronized void bowBack(Friend bower) { 
      System.out.format("%s: %s has bowed back to me!%n", 
        this.name, bower.getName()); 
     } 
    } 

    public static void main(String[] args) { 
     final Friend alphonse = new Friend("Alphonse"); 
     final Friend gaston = new Friend("Gaston"); 
     new Thread(new Runnable() { 
      public void run() { alphonse.bow(gaston); } 
     }).start(); 
     new Thread(new Runnable() { 
      public void run() { gaston.bow(alphonse); } 
     }).start(); 
    } 
} 

Khi deadlock chạy, rất có khả năng cả hai luồng sẽ chặn khi chúng cố gọi bowback. Cả hai khối sẽ không bao giờ kết thúc, bởi vì mỗi thread đang chờ người kia thoát khỏi cung.

+1

bản sao có thể có của [Cố gắng quấn bộ não của tôi xung quanh cách bế tắc của chuỗi chủ đề] (http://stackoverflow.com/questions/749641/trying-to-wrap-my-wee-brain-around-how-threads-deadlock) –

Trả lời

7

Phương pháp đồng bộ hóa (ví dụ) khóa trên đối tượng, KHÔNG ở trên lớp.

alphonse.bow lấy khóa trên alphonse và gaston.bow lấy khóa trên gaston. Khi sợi 'alphonse' đang ở trong cung, nó cố gắng lấy khóa trên 'gaston' tại bower.bowBack. Tương tự như vậy, 'gaston' cố gắng lấy khóa trên 'alphonse'.

Chỉnh sửa để rõ ràng (Tôi hy vọng):

Hãy gọi hai chuỗi Thread1 và Thread2.

Thread1 chạy alphonse.bow (gaston), nơi nó lấy khóa trên đối tượng alphonse trong khi Thread2 chạy gaston.bow (alphonse) và lấy khóa trên đối tượng dạ dày.

Trong Thread1, khi nó cố gắng chạy bower.bowBack (này), trong đó bower = gaston, chuỗi cần phải có khóa đầu tiên trên gaston.

Trong khi điều này đang diễn ra, Thread2 cố gắng làm điều tương tự, với bower = alphonse. Thread1 có một khóa mà Thread2 cần và ngược lại, đó là lý do tại sao bế tắc xảy ra.

Như một sang một bên, một bế tắc không cần phải luôn xảy ra. Nếu Thread1 có thể bắt đầu và kết thúc trước khi Thread2 có cơ hội để làm như vậy (ví dụ, nếu một cái gì đó treo thread chính sau khi Thread1 đã bắt đầu nhưng trước khi Thread2 được tạo/bắt đầu), thì không có bế tắc nào xảy ra.

+0

cách alphonse cố gắng lấy khóa trên dạ dày. alphonse luôn sử dụng cá thể alphonse. – jax

+0

Tôi không hiểu những điều sau đây "Khi chủ đề 'alphonse' được cung, nó cố gắng lấy khóa trên 'gaston' tại bower.bowBack." Làm thế nào là 'alphonse' cố gắng để có được một khóa trên trường hợp dạ dày. – jax

+0

Chủ đề đầu tiên gọi alphonse.bow (gaston). Tại thời điểm này, luồng có khóa trên alphonse. Khi phương thức đó được chuyển xuống bower.bowBack, nơi bower là gaston, nó cố gắng lấy khóa trên gaston. Bởi 'alphonse', tôi có nghĩa là chuỗi chạy 'alphonse.bow (gaston)'; xin lỗi nếu điều đó không rõ ràng. –