2012-07-23 19 views
17

Windows 7 işletim sistemini kullanıyorum. Uygulamamda yaklaşık 6 iş parçacığı var. Konuların sağlığını kontrol etmek için uyarıları test etmek amacıyla, iş parçacığı el ile öldürmem ve uyarıların düzgün çalışıp çalışmadığını kontrol etmem gerekiyor. pid ile bir işlemi nasıl öldürdüğümüz gibi bir iş parçacığını öldürebilir miyiz?VisualVM veya unix komutunu kullanarak bir java parçacığını nasıl öldürebilirsiniz?

+2

Konular, uygulamanın bir iç uygulama ayrıntısıdır. Uygulamanın dışında görünür veya erişilebilir değillerdir. Bir iş parçacığı beklenmedik bir şekilde ölürse, iş parçacıkları arasında bir yalıtım olmadığından uygulama kullanılamaz. (Eğer iş parçacığı bir kilit tutarsa ​​ne olacağını düşün. Eğer onu serbest bırakırsan, patlama. Eğer serbest bırakmazsan, patlama.) –

cevap

11

içinde bulunduğu süreci öldürmeden bir iplik "öldürmek" için güvenli bir yol yoktur. O değil kasten yapacağı bir şey. Test amaçlı olarak, bunu desteklemek için uygulamanıza kod ekleyeceğim.

+0

Teşekkürler Peter Lawrey. – Arun

+0

Ancak Thread.stop kullanarak kullanımdan kaldırılmıştır. Bunu faydalı buldum. http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html – Arun

+1

Bu yüzden dedim ki '' Bir iş parçacığını 'öldürmek için güvenli bir yol yoktur' Test amacıyla kullanmaktan sizi durdurun. –

2

Dışarıda (OS veya ayıklayıcıya) den bunu yapamaz, kullanıcı ile etkileşim ve istediğiniz iplik öldürebilir kendi Konu izleme örgütü yazmak gerekecek.

aşağıdaki gibi unix öldüremezsiniz java olarak java

0

ile sinyallerini nasıl işleneceğini için here bakmak için deneyin. Ya javadaki interrupt dişini yapabilirsin ya da işlemi Unix'te öldürebilirsin.

0

İş parçasında bir süre bekleyin ve iş parçacığı kodda öldürün - basit bir şekilde.

+0

Soruyu anladığınızı sanmıyorum ve Peter Lawrey'in söylediği gibi, Java iş parçacığını öldürmenin güvenli bir yolu yoktur. –

+0

@StephenC atma istisnası mı? – Mohan

+0

İşbirlikçi olmayan bir iş parçacığını bir istisna atamazsınız. Bu "kendini öldürmek" için bir iş parçacığı anlatmakla ilgili değil. Dinlemeyen bir iş parçacığını öldürmekle ilgili ... ve * üretimdeki bir uygulama hatasını * simüle edecek şekilde yapıyor. –

4

Peter'in dediği gibi, bunu güvenli bir şekilde yapamazsınız. Gerçekten de bazı platformlarda Thread.kill bile uygulanmamaktadır. Ancak:

  • bu test için sadece ise, o iş için gerekli deney platformlarında çalışan varsayarak Thread.kill mantıklı olacaktır denilen bir birim test .... (Kaynak kodunda "yüksek sesli" bir yorum, ünite testini gerçekleştiren kişilere yardımcı olmak için olacaktır ...)

  • Ünitelerin test etmesine izin veren iş parçacığına bir kod eklemek için başka bir alternatif ölmek. İş parçacığı kodunun bu işlemin çalışması için hemen hemen üretim kodu olması gerekiyorsa, bir şeyleri geçersiz kılacak bir alt sınıf oluşturabilir ve böylece testleriniz için amaçlarınıza uygun şekilde "kırılır". Aslında bu yaklaşım, iş parçacığının kontrollü yollarla "kırılmasına" neden olmanıza ve potansiyel olarak uyarı kodunuzun farklı yönlerini test etmenize olanak tanır. Dan Woods Bu blog girdisinde bir iş parçacığı öldürmek için nasıl dokümante

31

... O bir hata ayıklayıcı (jdb) kullanılarak ve parçacığının yürütülmesinde istisna enjekte dahil gerçekleştirilir https://web.archive.org/web/20160302023213/http://www.rhcedan.com/2010/06/22/killing-a-java-thread adım. Özellikle ...

  1. java programı aşağıdaki parametrelerle başlatıldığından emin olun:

    -Dcom.sun.management.jmxremote.port = 50199
    -Dcom.sun.management. jmxremote.authenticate = yanlış
    -Dcom.sun.management.jmxremote.ssl = yanlış
    -Xrunjdwp: taşıma = dt_socket, adresi = 50100, sunucu = y askıya = n

    Bu, java hata ayıklayıcısını çalışma sürecine eklememize olanak tanıyacak, 'dan sonra hangi iş parçacığının soruna neden olduğunu belirledik.Ayrıca, adresinin iptables kurulumunuza uygun bir şekilde sahip olduğunuzdan emin olun, böylece yalnızca yönettiğiniz ana makinelerden/iş istasyonlarından 50100 ve 50199 numaralı bağlantılarda bağlantılarına izin verin.

  2. Hatalı parçayı tanımlayın:
  3. Iş parçacığını öldürür. Bu örnekte ThreadName “btpool0-0?” Dur. bir listesini alın java ayıklayıcısını (ayrıca JDK dağıtımı ile birlikte gelen) çalıştır ve çalışan JVM eklemek ...

    [root @ konak ~] # çalýþtýrýr -attach 50100

çalışan iş parçacığı - JVM gördüğü gibi bu da bize parçacığı kimliği verecektir:

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

biz öldürecekler iplik kimliği “0x25cb” dir. iplik öldürme ilk adımı

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] 

Çık java ayıklayıcı ... içine atlamak ve bunu askıya etmektir ve bu kadar!

+2

ayrıca bir komut var: interrupt [threadid] – revo

2

Bu doğru değil. Her zaman GDB ile JVM sürecine ekleyebilir ve iş parçacığı kimliğini biliyorsanız bir pthread_kill çağrısı yapabilirsiniz. Sadece bir hex id, (yerel id) verir, daha sonra GDB (bilgi konuları) iş parçacığı listesine bakmak ve gerçek iş parçacığı kimliğini bulmak java iş parçacığı dökümü (bir kill -3) çevirmek gerekir.

Bunun ispatlandığı kanıtlanmıştır.

İlgili konular