2012-07-23 31 views
17

Tôi đang sử dụng hệ điều hành Windows 7. Tôi có khoảng 6 luồng trong ứng dụng của mình. Đối với mục đích kiểm tra các cảnh báo để kiểm tra sức khỏe của các chủ đề, tôi cần phải giết các chủ đề bằng tay và kiểm tra xem các cảnh báo đang hoạt động đúng. Chúng ta có thể giết một sợi giống như cách chúng ta giết một quá trình với pid của nó không?Làm thế nào để tiêu diệt một chuỗi java bằng VisualVM hoặc sử dụng lệnh unix?

+2

Chủ đề là chi tiết triển khai nội bộ của ứng dụng Chúng không hiển thị hoặc không thể truy cập từ bên ngoài ứng dụng. Nếu một chuỗi chết bất ngờ, ứng dụng sẽ không sử dụng được, vì không có sự cô lập giữa các luồng. (Hãy suy nghĩ về những gì sẽ xảy ra nếu chủ đề nắm giữ một khóa. Nếu bạn phát hành nó, bùng nổ. Nếu bạn không phát hành nó, bùng nổ.) –

Trả lời

11

Không có cách nào an toàn để "tiêu diệt" một chuỗi mà không giết chết quá trình. Đó không phải là điều bạn sẽ cố ý làm. Đối với mục đích thử nghiệm, tôi sẽ thêm mã vào ứng dụng của bạn để hỗ trợ điều này.

+0

Cảm ơn Peter Lawrey. – Arun

+0

Nhưng việc sử dụng Thread.stop không được chấp nhận. Tôi thấy điều này hữu ích. http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html – Arun

+1

Đó là lý do tại sao tôi nói 'Không có cách nào an toàn để "giết" chuỗi "Điều này không ngăn bạn sử dụng nó cho mục đích thử nghiệm. –

2

Bạn không thể làm điều đó từ bên ngoài (OS hoặc trình gỡ lỗi), bạn sẽ phải viết Trình theo dõi chủ đề của riêng mình có thể tương tác với người dùng và xóa chuỗi bạn muốn.

Hãy thử nhìn here cho làm thế nào để xử lý tín hiệu với java

0

Trong java bạn không thể giết như unix. Hoặc bạn có thể interrupt đường chạy trong java hoặc bạn có thể hủy quá trình trong unix.

0

Đợi một chút thời gian trong chuỗi và xóa chuỗi trong mã - cách đơn giản.

+0

Tôi không nghĩ rằng bạn hiểu câu hỏi, và dù sao đi nữa như Peter Lawrey nói, không có cách nào an toàn để giết một sợi Java. –

+0

@StephenC ném ngoại lệ? – Mohan

+0

Bạn không thể tạo một chuỗi không hợp tác ném một ngoại lệ. Đây không phải là nói một sợi để "tự sát". Đó là về việc giết một sợi không nghe ... và làm theo cách mà * mô phỏng * một lỗi ứng dụng trong sản xuất. –

4

Như Peter nói, bạn không thể làm điều này một cách an toàn. Thật vậy trên một số nền tảng Thread.kill thậm chí không được triển khai. Tuy nhiên:

  • Nếu đây là chỉ để thử nghiệm, một thử nghiệm đơn vị đó được gọi là Thread.kill sẽ là hợp lý ... giả sử nó làm việc trên nền tảng thử nghiệm nơi nó cần thiết để làm việc. (Nhận xét "lớn" trong mã nguồn sẽ giúp mọi người chuyển đổi kiểm tra đơn vị ...)

  • Một giải pháp thay thế khác là thêm một số mã vào chuỗi chạy cho phép kiểm tra đơn vị của bạn chết. Nếu mã thread cần phải được (gần như) mã sản xuất để làm việc này, bạn có thể tạo một lớp con ghi đè thứ gì đó để nó "phá vỡ" theo cách phù hợp với mục đích của bạn ... để thử nghiệm. Thực tế, cách tiếp cận này cho phép bạn tạo ra các luồng "ngắt" theo các cách được kiểm soát, có khả năng cho phép bạn kiểm tra các khía cạnh khác nhau của mã cảnh báo của bạn.

31

Dan Woods ghi nhận như thế nào để giết một thread trong blog entry này ... https://web.archive.org/web/20160302023213/http://www.rhcedan.com/2010/06/22/killing-a-java-thread Các bước ông đã thực hiện liên quan đến sử dụng một trình gỡ lỗi (JDB) và tiêm một ngoại lệ trong thực hiện của chủ đề. Cụ thể ...

  1. Đảm bảo rằng chương trình java của bạn được bắt đầu với các thông số sau:

    -Dcom.sun.management.jmxremote.port = 50.199
    -Dcom.sun.management. jmxremote.authenticate = false
    -Dcom.sun.management.jmxremote.ssl = false
    -Xrunjdwp: transport = dt_socket, địa chỉ = 50100, server = y, suspend = n

    Điều này sẽ cho phép chúng tôi đính kèm trình gỡ rối java vào quy trình đang chạy, sau chúng tôi xác định Chủ đề nào đang gây ra sự cố.Ngoài ra, hãy đảm bảo rằng bạn có thiết lập iptables của mình một cách thích hợp để chỉ cho phép các kết nối trên 50100 và 50199 từ máy chủ/máy trạm mà bạn quản lý.

  2. Xác định chủ đề vi phạm:
  3. Giết chủ đề. Trong ví dụ này, ThreadName là “btpool0-0 ?. Cháy lên trình gỡ lỗi java (còn vận chuyển với sự phân bố JDK), và gắn vào JVM chạy ...

    [root @ host ~] # JDB -attach 50100

Nhận một danh sách các chủ đề đang chạy - điều này cũng sẽ cung cấp cho chúng tôi id chủ đề khi JVM nhìn thấy nó:

> threads 
--snip-- 
(org.mortbay.thread.BoundedThreadPool$PoolThread)0x25cb 
btpool0-0 running 
--snip-- 

Id chủ đề mà chúng ta sẽ giết là “0x25cb”. Bước đầu tiên của việc giết sợi chỉ là nhảy vào nó, và đình chỉ nó…

thread 0x25cb 
btpool0-0[1] suspend 0x25cb 
btpool0-0[1] step 
Step completed: <... snip ...> 
btpool0-0[1] kill 0x25cb new java.lang.Exception() 
killing thread: btpool0-0 
btpool0-0[1] instance of 
com.site.package.name(name='btpool0-0', id=9675) killed btpool0-0[1] 

Thoát trình gỡ rối java, và bạn đã hoàn tất!

+2

cũng có lệnh: ngắt [threadid] – revo

2

Điều đó không đúng. Bạn luôn có thể đính kèm vào quy trình JVM với GDB và thực hiện cuộc gọi pthread_kill nếu bạn biết id luồng. Bạn chỉ cần dịch từ kết xuất chuỗi java (làm một kill -3) cho bạn một id hex, (id gốc), sau đó nhìn vào danh sách các luồng trong GDB (các luồng thông tin) và định vị id thread thực.

Điều này được chứng minh là có hiệu quả.

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