2010-09-17 45 views
9

Tôi có một ứng dụng đa luồng. Một số tin nhắn đến ứng dụng và được xử lý trong các chủ đề riêng biệt. Đối với điều này tôi đang sử dụng các lớp ThreadPoolExecutor và FutureTask từ gói java.util.concurrent.Cách lấy dấu vết ngăn xếp của một chủ đề

Thỉnh thoảng tôi có một số bế tắc trong ứng dụng. Khi bế tắc xảy ra, tôi muốn ngắt chuỗi chặn và tôi muốn ghi lại dấu vết ngăn xếp của luồng này để sau này tôi có thể giải quyết bế tắc.

Có cách nào để chúng tôi có thể tìm thấy dấu vết ngăn xếp của một chuỗi bên ngoài chuỗi đó trong Java không?

+0

Bạn có nghĩa là bạn muốn phát hiện bế tắc và khôi phục? Không bao giờ làm điều đó, nhưng bằng cách sử dụng một dấu vết ngăn xếp cho rằng không âm thanh như đúng cách để tôi .. –

+0

Tôi cần theo dõi ngăn xếp để tôi biết nơi mà các chủ đề bị mắc kẹt và có thể khắc phục vấn đề để ứng dụng hoạt động ngay sau khi khởi động lại. Tuy nhiên tôi muốn ngắt chuỗi chặn để ứng dụng hoạt động cho đến khi tôi tìm thấy một số thời gian để khắc phục sự cố và giải phóng nó. – Palo

Trả lời

5

Xem here để biết cách tạo dấu vết ngăn xếp, bao gồm cách thực hiện việc này theo chương trình. Từ bảng điều khiển, Ctrl + Break sẽ đổ các dấu vết ngăn xếp để xuất chuẩn. Xem thêm this SO question để biết thêm chi tiết.

+5

Trong môi trường UNIX, việc gửi tín hiệu “QUIT” ('kill -QUIT ') đến quá trình java cũng sẽ xuất ra dấu vết ngăn xếp đến đầu ra tiêu chuẩn. – Bombe

5

Bạn có thể ghi lại các dấu vết ngăn xếp của tất cả các chuỗi theo thời gian (hoặc trước khi hủy quá trình) từ bên trong ứng dụng của bạn. Để thực hiện việc đó:

Map<Thread, StackTraceElement[]> m = Thread.getAllStackTraces(); 
for(Map.Entry<Thread, StackTraceElement[]> e : m.entrySet()) { 
    log(e.getKey().toString()); 
    for (StackTraceElement s : e.getValue()) { 
     log(" " + s); 
    } 
} 

Khi chạy kiểm tra tự động hàng đêm, đôi khi một số trường hợp thử nghiệm bị bế tắc. Tôi đã thêm một chuỗi chủ đề "TimeBomb" chờ 30 phút, và nếu sau đó ghi lại tất cả các dấu vết ngăn xếp như trên.

0

Tôi đã không chắc chắn nếu bạn muốn để có được những stacktrace từ bên trong JVM cùng hoặc bên ngoài, nhưng nếu bạn muốn để có được những dấu vết ngăn xếp với các công cụ bên ngoài, sau đây sẽ giúp:

  • The Java VisualVM công cụ có thể được sử dụng để kết nối với JVM đang chạy, nơi ngăn xếp luồng có thể được bán phá giá. Đây thường là cách tiếp cận ưa thích cho hầu hết mọi người khi sử dụng Java 6. Khi VisualVM được khởi chạy, kết xuất chuỗi của quá trình có thể thu được bằng cách chọn quy trình trong tab Ứng dụng. Một tab Threads hiện đã có sẵn để xem các luồng trong tiến trình đang chạy, và trong cùng một tab, bạn sẽ tìm thấy nút "Thread Dump" để trích xuất các thông tin cần thiết.
  • Tiện ích jstack trong JDK cũng có thể được sử dụng để tạo ngăn xếp chủ đề.
2

Bạn sử dụng JStack. Đây là một blog entry đẹp chi tiết cách để có được dấu vết ngăn xếp.

4

Trước khi bước vào khu vực bế tắc, thiết lập một lĩnh vực như,

thread = Thread.currentThread(); 

Trong chủ đề giám sát của bạn, bạn có thể thực hiện thread.getStackTrace(); để có được những đống dấu vết của chủ đề mà bất cứ lúc nào.

0

Khi một bế tắc xảy ra tôi muốn ngắt thread chặn ...

Bạn thể thực hiện một công việc định kỳ để kiểm tra sự bế tắc (nơi deadlocks là java nội tại hoặc Lock dựa) và cuộc gọi interrupt trên tất cả các chủ đề liên quan đến kịch bản. Tuy nhiên, điều này không đảm bảo rằng nó sẽ giải quyết vấn đề của bạn. Có khả năng kịch bản đó sẽ lại xảy ra. Xem Dr Heinz's article on a deadlock detector để biết chi tiết.

Nếu thực tế, không có đảm bảo rằng interrupt thậm chí sẽ giải phóng một quy trình bị chặn như thế này. Cách tiếp cận tốt hơn nhiều của nó để tránh tình huống bế tắc ở nơi đầu tiên bằng cách sử dụng các khóa có thời gian chờ và thử lại các chiến lược hoặc phương pháp 'thử trước khi bạn mua'.

và tôi muốn ghi lại những ngăn xếp dấu vết của chủ đề này ...

Nếu bạn muốn làm điều này programatically, một lần nữa, hãy làm theo ví dụ Tiến sĩ Heinz. Nếu không, chỉ cần tạo kết xuất chuỗi khi bạn đã phát hiện sự cố.

Có cách nào để chúng tôi có thể tìm ra dấu vết ngăn xếp của một chuỗi bên ngoài chuỗi đó trong Java không?

Có và không. Bạn có thể đổ các chủ đề từ các máy ảo khác nhưng dấu vết ngăn xếp của chúng có thể không hữu ích như bạn nghĩ để xác định nguyên nhân gây ra bế tắc của bạn. Nếu một bế tắc chính hãng đã được phát hiện (bởi chính JVM trên kết xuất chuỗi máy ảo ứng dụng của bạn), bạn nên có mọi thứ bạn cần để gỡ lỗi nguyên nhân (nhiều hơn hoặc ít hơn).

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