Java.lang.Thread.interrupt () ne yapıyor?


Yanıtlar:


250

Thread.interrupt()hedef iş parçacığının kesilmiş durumunu / bayrağını ayarlar. Daha sonra bu hedef iş parçacığında çalışan kod, kesilen durumu yoklayabilir ve uygun şekilde işleyebilir. Engellenen bazı yöntemler Object.wait(), kesilen durumu hemen tüketebilir ve uygun bir istisna atabilir (genellikle InterruptedException)

Java'da kesinti önleyici değildir. Kesmeyi düzgün bir şekilde işlemek için her iki iş parçacığının da işbirliği yapması gereken başka bir yol koyun. Hedef iş parçacığı kesintiye uğramış durumu yok etmezse, kesme etkin bir şekilde yoksayılır.

Yoklama Thread.interrupted(), geçerli iş parçacığının kesilmiş durumunu döndüren VE kesme bayrağını silen yöntemle gerçekleşir. Genellikle iş parçacığı sonra InterruptedException atmak gibi bir şey yapabilir.

EDIT (Thilo yorumlarından): Bazı API yöntemleri kesinti işlemede yerleşiktir. Başımın üst kısmı buna dahildir.

  • Object.wait(), Thread.sleep()VeThread.join()
  • Çoğu java.util.concurrentyapı
  • Java NIO (ancak java.io değil) ve bunun InterruptedExceptionyerine kullanmak DEĞİLDİR ClosedByInterruptException.

EDIT ( @ thomas-pornin 'in tamlık için aynı soruya cevabı )

İplik kesilmesi, bir ipliği dürtmenin yumuşak bir yoludur. Dişlere temiz bir şekilde çıkma şansı vermek için kullanılır , aksine Thread.stop()dişi bir saldırı tüfeği ile vurmaya benzer.


22
Uyku veya bekleme gibi yöntemlerin bu tür bir yoklama yaptığını ve InterruptedException'ı kendileri attığını unutmayın.
Thilo

1
Kesilebilir dosya G / Ç kullanıyorsanız, etki o kadar yumuşak olmaz. Genellikle dosya bozulması alırsınız.
Marko Topolnik

Thread.interrupted'tan bahsediyorsanız, bir Thread.isInterrupted bayrağı da olduğu belirtilmelidir, bu da bayrağı temizlemez, bu da genellikle uygulama geliştiricileri tarafından kullanım için daha uygun hale getirir.
Nathan Hughes

67

Kesme nedir?

Kesme, bir iş parçacığının yaptıklarını durdurması ve başka bir şey yapması gerektiğinin bir göstergesidir. Bir iş parçacığının kesmeye tam olarak nasıl tepki verdiğine karar vermek programcıya bağlıdır, ancak iş parçacığının sonlanması çok yaygındır.

Nasıl uygulanır?

Kesme mekanizması, kesme durumu olarak bilinen dahili bir bayrak kullanılarak uygulanır. Thread.interrupt bu çağrıyı ayarlar. Bir evre Thread.interrupted statik yöntemini çağırarak bir kesinti olup olmadığını kontrol ettiğinde, kesme durumu temizlenir. Bir iş parçacığı tarafından bir başkasının kesme durumunu sorgulamak için kullanılan statik olmayan Thread.isInterrupted, kesme durumu bayrağını değiştirmez.

Thread.interrupt()API'dan alıntı :

Bu iş parçacığını keser. Önce bu iş parçacığının checkAccess yöntemi çağrılır ve bu da bir SecurityException özel durumunun atılmasına neden olabilir.

Bu iş parçacığı Object sınıfının wait (), wait (uzun) veya wait (long, int) yöntemlerinin çağrılmasıyla engellenirse, join (uzun), join (long, int) , uyku (uzun) veya uyku (uzun, int), bu sınıfın yöntemleri, daha sonra kesme durumu silinir ve bir InterruptedException alır.

Bu iş parçacığı, kesilebilir bir kanal üzerinde bir G / Ç işleminde engellenirse, kanal kapatılır, iş parçacığının kesme durumu ayarlanır ve iş parçacığı ClosedByInterruptException alır.

Bu iş parçacığı bir Seçici'de engellenirse, iş parçacığının kesme durumu ayarlanır ve seçicinin uyandırma yöntemi çağrılmış gibi muhtemelen sıfırdan farklı bir değerle seçim işleminden hemen geri döner.

Önceki koşullardan hiçbiri geçerli değilse, bu iş parçacığının kesme durumu ayarlanır.

Bununla ilgili tam bir anlayış için buna göz atın:

http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html


Bu kısmi bir açıklamaya uymaktır. Ayrıca kesilebilir yöntemleri de keser.
Lorne Marquis

@EJP Bu soru, Thread.interrupt () yöntemi nedir ve nasıl çalışır? Sanırım linkle paylaştığım her ne olursa olsun, sorulan sorulara cevap veriyor. Hala ne istediğini anlamıyorum?
YoK

Bayrağın uyguladığına ilişkin kısmen yanlış beyanınızı düzeltmenizi dilerim. Bu hikayenin sadece bir parçası. Bana çok açık geliyor.
Marquis of Lorne

@EJP Teşekkürler. Şimdi ne dediğini anlıyorum. Cevabımı güncelledim ve yöntem için API dokümanını ekledim. Bu, cevabımda eksik olan kesilebilir yöntemler bölümünü kapsıyor. Umarım cevabım şimdi tam görünüyor :).
YoK

13

Hedeflenen iş parçacığı beklemişse (arayarak wait()veya esasen aynı şeyi yapan diğer ilgili yöntemleri kullanarak sleep()), kesilir, yani beklediğini beklemeyi bırakır ve bunun yerine bir InterruptedException alır.

Bu durumda wait()ne yapılacağına karar vermek tamamen iş parçacığının kendisine (çağrılan kod ) bağlıdır. İş parçacığını otomatik olarak sonlandırmaz.

Bazen sonlandırma bayrağıyla birlikte kullanılır. Kesildiğinde, iş parçacığı bu bayrağı kontrol edebilir ve sonra kendini kapatabilir. Ama yine de, bu sadece bir kongre.


9 yaşında, yaşlanmayan cevap! +1
snr

10

Bütünlüğü sağlamak için, diğer cevaplar ek olarak, iplik üzerinde bulunan blok önce kesildiğinde Object.wait(..)ya da Thread.sleep(..), bu, bu yönteme bloklama derhal durdurulur buna denktir aşağıdaki örnekte gösterildiği gibi,.

public class InterruptTest {
    public static void main(String[] args) {

        Thread.currentThread().interrupt();

        printInterrupted(1);

        Object o = new Object();
        try {
            synchronized (o) {
                printInterrupted(2);
                System.out.printf("A Time %d\n", System.currentTimeMillis());
                o.wait(100);
                System.out.printf("B Time %d\n", System.currentTimeMillis());
            }
        } catch (InterruptedException ie) {
            System.out.printf("WAS interrupted\n");
        }
        System.out.printf("C Time %d\n", System.currentTimeMillis());

        printInterrupted(3);

        Thread.currentThread().interrupt();

        printInterrupted(4);

        try {
            System.out.printf("D Time %d\n", System.currentTimeMillis());
            Thread.sleep(100);
            System.out.printf("E Time %d\n", System.currentTimeMillis());
        } catch (InterruptedException ie) {
            System.out.printf("WAS interrupted\n");
        }
        System.out.printf("F Time %d\n", System.currentTimeMillis());

        printInterrupted(5);

        try {
            System.out.printf("G Time %d\n", System.currentTimeMillis());
            Thread.sleep(100);
            System.out.printf("H Time %d\n", System.currentTimeMillis());
        } catch (InterruptedException ie) {
            System.out.printf("WAS interrupted\n");
        }
        System.out.printf("I Time %d\n", System.currentTimeMillis());

    }
    static void printInterrupted(int n) {
        System.out.printf("(%d) Am I interrupted? %s\n", n,
                Thread.currentThread().isInterrupted() ? "Yes" : "No");
    }
}

Çıktı:

$ javac InterruptTest.java 

$ java -classpath "." InterruptTest
(1) Am I interrupted? Yes
(2) Am I interrupted? Yes
A Time 1399207408543
WAS interrupted
C Time 1399207408543
(3) Am I interrupted? No
(4) Am I interrupted? Yes
D Time 1399207408544
WAS interrupted
F Time 1399207408544
(5) Am I interrupted? No
G Time 1399207408545
H Time 1399207408668
I Time 1399207408669

Sonuç: Aşağıdaki gibi döngü yaparsanız ve kesinti, denetimden ayrıldığında Thread.sleep(..)ve döngüde dolaşırken tam olarak gerçekleşirse, istisna yine de gerçekleşir. Bu nedenle, iş parçacığı kesildikten sonra güvenilir bir şekilde atılan InterruptedException öğesine güvenmek tamamen güvenlidir :

while (true) {
    try {
        Thread.sleep(10);
    } catch (InterruptedException ie) {
        break;
    }
}


4

İş parçacığı kesintisi bayrak kesme durumuna dayanır . Her iş parçacığı için kesinti durumunun varsayılan değeri false olarak ayarlanır . İş parçacığında interrupt () yöntemi çağrıldığında, kesme durumu true olarak ayarlanır .

  1. Kesme durum özellikle iplik doğrudur (zaten iş parçacığı üzerinde denir kesme ()), = Eğer edemez uyu. Bu iş parçacığında uyku çağrılırsa kesilen istisna atılır. İstisna tekrar atıldıktan sonra bayrak yanlış olarak ayarlanır.
  2. İş parçacığı zaten uykudaysa ve interrupt () çağrılırsa, iş parçacığı uyku durumundan çıkar ve kesilen İstisna atar.

1

kamu boşluğu kesintisi ()

Bu iş parçacığını keser.

Geçerli iş parçacığı her zaman izin verilen kendini kesmezse, bu iş parçacığının checkAccess yöntemi çağrılır ve bu da bir SecurityException özel durumunun atılmasına neden olabilir.

Bu iş parçacığı Object sınıfının wait (), wait (uzun) veya wait (long, int) yöntemlerinin çağrılmasıyla engellenirse, join (uzun), join (long, int) , uyku (uzun) veya uyku (uzun, int), bu sınıfın yöntemleri, daha sonra kesme durumu silinir ve bir InterruptedException alır.

Bu iş parçacığı, kesilebilir bir kanal üzerinde bir G / Ç işleminde engellenirse, kanal kapatılır, iş parçacığının kesme durumu ayarlanır ve iş parçacığı ClosedByInterruptException alır.

Bu iş parçacığı bir Seçici'de engellenirse, iş parçacığının kesme durumu ayarlanır ve seçicinin uyandırma yöntemi çağrılmış gibi muhtemelen sıfırdan farklı bir değerle seçim işleminden hemen geri döner.

Önceki koşullardan hiçbiri geçerli değilse, bu iş parçacığının kesme durumu ayarlanır.

Canlı olmayan bir iş parçacığının kesilmesinin herhangi bir etkisi olması gerekmez.

Atar: SecurityException - geçerli iş parçacığı bu iş parçacığını değiştiremezse



1

Thread.interrupt () yöntemi dahili 'kesinti durumu' bayrağını ayarlar. Genellikle bu bayrak Thread.interrupted () yöntemi ile kontrol edilir.

Kural olarak, InterruptedException aracılığıyla var olan herhangi bir yöntem kesinti durum bayrağını temizlemek zorundadır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.