2010-07-13 30 views
9

Tôi có một ứng dụng Java không kết thúc. Phương thức chính kết thúc, nhưng chủ đề vẫn hoạt động và ứng dụng không kết thúc. Vấn đề là, có vẻ như không có bất kỳ khóa màn hình/chờ đợi, vì vậy tôi không thể nhìn thấy lý do tại sao nó không kết thúc. Theo Eclipse, tôi còn lại với hai luồng không phải là Daemon. Một được gắn nhãn [DestroyJavaVM] (có vẻ hy vọng!) Và cái kia có vẻ bị chặn trong Unsafe.park(boolean, long). Tôi nên bắt đầu điều tra ở đâu đây?Tôi bắt đầu điều tra quá trình Java của mình ở đâu sẽ không kết thúc?

Các stacktrace tóm tắt của các chủ đề thứ hai là:

Unsafe.park(boolean, long) 
at LockSupport.park(Object) 
at AbstractQueuedSynchronizer$ConditionObject.await() 
at LinkedBlockingQueue<E>.take() 
at ThreadPoolExecutor.getTask() 
at ThreadPoolExecutor$Worker.run() 
at Thread.run() 
+0

Dấu vết ngăn xếp đầy đủ của chuỗi trong Unsafe.park() là gì? –

+0

Unsafe.park (boolean, long) -> LockSupport.park (Object) -> AbstractQueuedSynchronizer $ ConditionObject.await() -> LinkedBlockingQueue .take() -> ThreadPoolExecutor.getTask() -> ThreadPoolExecutor $ Worker.run() -> Chủ đề.run() – JenFallow

+0

Tôi đã chỉnh sửa bình luận của bạn thành câu hỏi bởi vì nó dễ đọc hơn trong một khối mã, và vì nó tạo thành một phần quan trọng của câu hỏi. –

Trả lời

0

bãi Chủ đề và gỡ rối sẽ là tôi đoán.

0

Không chắc chắn ứng dụng lớn như thế nào nhưng tôi sẽ kiểm tra tất cả các Chủ đề bạn đã tạo và đảm bảo rằng các phương thức chạy của chúng được xóa sạch khi ứng dụng được thực hiện xong. Một nơi nào đó, trong một chủ đề, bạn có thể có mã dọc theo dòng:

public void run() { 
    while(true) { //"true" or some condition that never gets a chance to be false 
     //do thread related work 
    } 
} 
0

Unsafe.park, mặc dù tên đáng sợ-sounding, thường được sử dụng bởi tất cả các loại chặn cuộc gọi (đặc biệt là những người trong mới (ish) java.util.concurrent gói).

Nếu bạn nhìn thêm một vài khung xuống dưới ngăn xếp, bạn sẽ thấy một cái gì đó như java.util.concurrent.LinkedBlockingQueue.take (ví dụ: một số lớp thư viện JDK) theo sau là một cái gì đó như com.example.myapp.MyClass.getNextJob (tức là lớp của bạn đang sử dụng lớp thư viện).

Nếu tôi phải dự đoán nguy hiểm, tôi muốn nói rằng bạn đang thực hiện một số cuộc gọi chặn vĩnh viễn - và vì vậy khi không còn gì để quay trở lại, chủ đề này chỉ ngồi đó chờ mục "tiếp theo" . Bạn có thể giải quyết điều này bằng cách thiết lập một số loại "hoàn thành" cờ, và sau đó hoặc là gián đoạn thread chờ đợi hoặc cho các cuộc gọi chặn một thời gian chờ, nhận được nó để kiểm tra cờ. Tùy thuộc vào mã của bạn trong số này hoặc một giải pháp thay thế có thể khả thi, nhưng hy vọng điều này là đủ để bạn bắt đầu.

Chỉnh sửa: sau khi xem stacktrace, finnw is right mà bạn cần phải tắt dịch vụ thi hành của mình.

1

Bạn cần phải làm một trong hai điều để chấm dứt ExecutorService chủ đề của bạn: (. Lớp ThreadFactoryBuilder từ Guava sẽ làm cho điều này dễ dàng hơn)

  1. Chỉ định ThreadFactory tạo chủ đề daemon
  2. Gọi shutdown() trên của bạn ExecutorService là một phần của quá trình tắt ứng dụng (ví dụ: ở cuối phương thức main của bạn.)
+0

+1: 'shutdown()' là cách kinh điển để làm điều này - các chuỗi daemon sẽ ngăn chặn vấn đề này nhưng có thể không phải là những gì mong muốn và * có thể * dẫn đến các vấn đề sau này. –

0

Nhiệm vụ của bạn là bị chặn chờ dữ liệu từ hàng đợi. Take không có một thời gian chờ liên kết với nó.

Duy trì tham chiếu đến chuỗi nhiệm vụ của bạn khi được tạo. Khi tắt máy, hãy gọi phương thức ngắt trên luồng. Bạn cũng có thể cần phải sửa đổi vòng lặp xử lý công việc mà các cuộc gọi thực hiện để thoát khi InterruptedException bị bắt.

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