2015-05-16 23 views
5

Tôi muốn chạy hai chủ đề cái khác, không sử dụng sleep() hoặc Locks, nhưng bế tắc sẽ xảy ra! Có gì sai với mã của tôi? Tôi đã sử dụng wait() và thông báoAllAll() và một đối tượng Object.Java chờ và thông báo làm bế tắc

public class Test { 

    public static void main(String[] args) throws InterruptedException { 
     PrintChar a = new PrintChar('a'); 
     PrintChar b = new PrintChar('b'); 
     Thread ta = new Thread(a); 
     Thread tb = new Thread(b); 
     ta.start(); 
     tb.start(); 
    } 
} 

class PrintChar implements Runnable { 
    final Object o = new Object(); 
    char ch; 
    public PrintChar(char a) { 
     ch = a; 
    } 

    @Override 
    public void run() { 
     for (int i = 0; i < 100; i++) { 
      synchronized (o) { 
       System.out.print(ch); 
       try { 
        o.wait(); 
        o.notifyAll(); 
       } catch (InterruptedException ex) { 
       } 
      } 
     } 
    } 
} 
+2

Tôi không bao giờ hiểu được những câu hỏi này. Nếu bạn muốn thực hiện tuần tự, tại sao bạn sử dụng các chủ đề? – EJP

+0

Đừng bận tâm đến EJP! Chỉ cần thực hành! – John

Trả lời

7

Chạy mã của bạn và nhìn vào nó, tôi thấy rằng mỗi chuỗi bạn tạo ra đang tạo và đồng bộ hóa với đối tượng riêng của nó, do đó ngăn không cho chúng thông báo cho nhau. Tôi cũng thấy rằng bạn chờ đợi trước khi thông báo, vì vậy bạn không bao giờ nhận được để gọi o.notifyAll(), vì o.wait() dừng trước tiên.

Thay đổi final Object o = new Object() để static final Object o = new Object(), và chuyển đổi nơi o.wait()o.notifyAll()

-1

Tôi nghĩ rằng khối synchronized gây ra bế tắc. Cos nó sẽ không để cho thread khác bắt đầu cho đến khi một trong những hiện tại kết thúc. Bạn đang sử dụng phương thức wait() để làm cho chuỗi hiện tại đang chờ. Ok, nó sẽ đợi nhưng vì nó nằm trong khối synchronized, nó sẽ nằm trong luồng hiện tại mãi mãi không bao giờ cho phép bất kỳ chủ đề nào khác tồn tại vì synchronized.

Một điều bạn có thể làm để làm cho luồng khác hoạt động là sử dụng Thread.stop. Hãy thử gọi số stop method trong tham chiếu của chuỗi hiện tại. Nhưng tôi không chắc liệu nó sẽ cho phép thread hiện tại bắt đầu lại hay không.

+0

nhưng chắc chắn điều này sẽ bắt đầu thread khác theo câu hỏi của bạn mà không sử dụng ** sleep() ** :) – Choxx

+2

Điều này là sai, vì một nửa hàm của 'Object.wait()' là giải phóng nguyên tử khóa được giữ trên nó. Nó thực sự cần thiết để được gọi từ bên trong một khối 'đồng bộ' trên đối tượng được đề cập. – Dolda2000

Các vấn đề liên quan