2010-04-19 49 views
6

Tôi có đoạn mã sau:Tại sao ngắt lời tuyên bố này không hoạt động?

public void post(String message) { 
    final String mess = message; 
    (new Thread() { 
     public void run() { 
      while (true) { 
       try { 
        if (status.equals("serviceResolved")) { 
         output.println(mess); 
         Game.log.fine("The following message was successfully sent: " + mess); 
         break; 
        } else { 
         try {Thread.sleep(1000);} catch (InterruptedException ie) {} 
        } 
       } catch (NullPointerException e) { 
        try {Thread.sleep(1000);} catch (InterruptedException ie) {} 
       } 
      } 
     } 
    }).start(); 
} 

Trong log file của tôi, tôi tìm thấy rất nhiều dòng như thế này:

The following message was successfully sent: blablabla 
The following message was successfully sent: blablabla 
The following message was successfully sent: blablabla 
The following message was successfully sent: blablabla 

Và chương trình của tôi không được đáp ứng.

Dường như với tôi rằng lệnh break không hoạt động. Điều gì có thể là một lý do có thể cho điều đó.

Điều thú vị là nó không phải lúc nào cũng xảy ra. Đôi khi chương trình của tôi hoạt động tốt, đôi khi vấn đề được mô tả ở trên xảy ra.

+0

FWIW: bạn có thể đưa ra hai dòng Thread.sleep() vào một dòng được thực hiện sau lần thử/bắt ngoài cùng. –

+2

Việc bắt giữ 'NullPointerException' dường như không phải là một ý tưởng hay (có nghĩa là phải kiểm tra xem liệu' status == null' - nếu như vậy hãy kiểm tra liệu 'status' là' null' thay thế).Và 'InterruptedException' nên được thực hiện để thoát ra khỏi vòng lặp (không phải là tôi thích thread ngắt, nhưng nó là có và do đó nên được xử lý)./Ngoài ra bạn có thể tạo tham số 'final', vì vậy bạn không cần copy' mess'. –

+0

Đây là lý do rõ ràng lý do tại sao bạn không bao giờ nên im lặng một ngoại lệ trừ khi bạn thực sự cần phải làm điều đó: gỡ lỗi trở thành địa ngục. – Jack

Trả lời

3

Bạn đang bắt đầu một chuỗi mới mỗi lần bạn gọi phương thức bài đăng. Tôi điều phương pháp là OK nhưng chương trình người gọi không phải là.

+0

có lẽ nên sử dụng hàng đợi, với tác vụ chuỗi/người thi hành được bắt đầu một lần và đọc hàng đợi –

+0

Bạn đúng. Tôi đã có nhiều dòng thông điệp vì mã đã cho ở trên được gọi nhiều lần và nó được gọi nhiều lần vì tôi nhấn nút gửi nhiều lần (khi chương trình của tôi bị đóng băng). Và chương trình của tôi bị đóng băng vì một sai lầm ngu ngốc khác không liên quan đến mã đã cho. – Roman

4

Nó có thể được rằng dòng này thành công:

output.println(mess); 

nhưng dòng này là ném một con trỏ ngoại lệ null:

Game.log.fine(... 

Trong trường hợp này bạn sẽ thấy đầu ra trên giao diện điều khiển, nhưng tuyên bố phá vỡ không bao giờ đạt được. Có phải Game.log có lẽ là không?

+1

Điều này không thể, bởi vì anh ta báo cáo thấy 'Thông báo sau được gửi thành công:', là từ dòng 'Game.log'. – polygenelubricants

+1

Tôi có thiếu gì đó không? OP nói rằng anh ta đang nhận được kết quả đầu ra, có nghĩa là 'Game.log' không thể là' null' ... –

+0

Tôi cũng sẽ coi nó như một bài học giảm thiểu phạm vi của các khối thử để ý nghĩa hơn. –

4

Game.log.fine chính xác làm gì? Nó có thể được rằng nó ném một NullPtrException sau khi đầu ra, hoặc nó có thể được rằng bạn gọi phương pháp sau nhiều lần?

Loại bỏ bắt của NullPointerException, đây là kiểu xấu (xuất hiện NullPointerException luôn là lỗi lập trình) và thêm một số thông điệp tường trình khác trong phương thức (hoặc sử dụng trình gỡ lỗi).

2

Bạn có chắc chắn muốn tiếp tục NullPointerException không? Nếu bạn nhận được một bên trong vòng lặp, bạn có thể chờ đợi mãi mãi.

Nếu bạn chắc chắn rằng status sẽ luôn cuối cùng được "serviceResolved", sau đó đặt một try ... finally bên trong câu lệnh if để nếu một cái gì đó thất bại, vòng lặp vẫn tồn tại:

if (status.equals("serviceResolved")) { 
    // No matter what happens next, we have to bail 
    try { 
     output.println(mess); 
     Game.log.fine("The following message was successfully sent: " + mess); 
    } finally { 
     break; 
    } 
} else { 
    try {Thread.sleep(1000);} catch (InterruptedException ie) {} 
} 
0

Bạn 'giả định rằng câu lệnh break không hoạt động, nhưng có thể là phương pháp post của bạn đang được gọi nhiều lần. Thử đặt một câu lệnh nhật ký khác ở đầu phương thức để xem tần suất nó được gọi. Ngoài ra, hãy đặt câu lệnh nhật ký sau vòng lặp while nhưng trước khi kết thúc phương thức run để xác minh rằng break thực sự đã thoát ra khỏi vòng lặp.

Tôi cũng đồng ý với các áp phích khác bắt được NullPointerException là một mùi mã. Bạn nên kiểm tra các biến của mình trước tiên cho null.

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