Java'da bir Konuyu nasıl öldürürsünüz?


374

java.lang.ThreadJava'da nasıl öldürürsün ?


2
şimdiye kadar bir iplik öldüremezsiniz; çünkü destroy () hiçbir zaman ölü kilitli eğilimli nedeniyle uygulanmaz
AZ_

1
Bu soruya ilişkin cevabı tercih ederim ExecutorStatus: stackoverflow.com/questions/2275443/how-to-timeout-a-thread
Kirby

9
@loungerdork "Java, kilitleri ve diğer tuzakları kaybetme uyarılarına rağmen üzerinde kontrole sahip olmayan kaçak iplikler için güvenli bir durdurma / yok etme yöntemi uygulamalıdır" Bu yüzden güvenli olmayan bir iplik durağı istiyorsunuz . Sanırım zaten bir tane var.
DJClayworth

4
2009'da ne tür soruların 212 upvotes alacağı şaşırtıcı. Bugün hemen imha edilecek.
Jonathon Reinhart

7
@JonathonReinhart: Neden böyle? Bugünlerde bile yasal bir soru gibi görünüyor. Belki kaçak iş parçacıkları olduğunda neden olan hayal kırıklığını bilmiyorsun ve sadece bir şekilde işlemek için kullanımdan kaldırılmış işlevleri kullanabilirsiniz?
TFuto

Yanıtlar:


189

Sun'ın neden kullanımdan kaldırıldığına dairThread.stop() bu konuya bakın . Bunun neden kötü bir yöntem olduğu ve genel olarak konuları güvenli bir şekilde durdurmak için ne yapılması gerektiği hakkında ayrıntılara girer.

Önerdikleri yol, arka plan iş parçacığının durmasını isteyen bir bayrak olarak paylaşılan bir değişken kullanmaktır. Bu değişken daha sonra iş parçacığının sonlandırılmasını isteyen farklı bir nesne tarafından ayarlanabilir.


1
isAlive () 'yi kestiğiniz iş parçacığını kontrol ederseniz, size true değerini döndürür ve geçerli ThreadGroup [] öğenize eklemeye devam ederler, bunu Thread.currentThread.getThreadGroup (). list (); sahip olduğu tüm iş parçacıklarını yazdırır ve akışınızı tekrarlarsanız iş parçacığınızın birden çok örneğini görürsünüz.
AZ_

3
Eğer bir PC iseniz o zaman onun sorun değil ama mobil için bir yazılım geliştiriyorsanız (android ben bunu yaşadım) o zaman OutOfMemoryError
AZ_

2
Durdurma talebinin bayrak yoluyla hızlı bir şekilde iletilmesini sağlamak için, değişkente, öneride belirtildiği gibi değişken olması (veya değişkene erişimin senkronize edilmesi gerekir) not edilmelidir.
mtsz

2
Bu bağlantı bu noktada öldürüldü. Yine de archive.org'da bulabildim: web.archive.org/web/20090202093154/http://java.sun.com/j2se/…
Jay Taylor

2
Ben yöntemi kullanmak getConnection()den java.sql.DriverManager. Bağlantı girişimi çok uzun sürerse, karşılık gelen iş parçacığını arayarak öldürmeye çalışırım Thread.interrupt()ama iş parçacığını hiç etkilemez. Ancak Thread.stop()eserler, eğer işe interrupt()yaramazsa çalışmaması gerektiğini söylüyor . Nasıl çalıştığını merak ediyorum ve kullanımdan kaldırılmış yöntemi kullanmaktan kaçının.
Danny Lo

129

Genellikle yapmazsınız ..

Thread.interrupt () (javadoc link) kullanarak ne yapıyorsa onu kesmesini istersiniz.

Javadoc'un neden burada olduğuna dair iyi bir açıklama (java technote link)


@Fredrik interrupt()Yöntem çağrıldığında Thread bağlamına ne olur ? Ana soru, her yeni evre için günlük oluşturma ile ilgilidir .
ABcDexter

3
@ABcDexter Kesinti, kesmenin hiçbir şeyi kesintiye uğratmaması, sadece iş parçacığındaki koda (ya da iş parçacığı tarafından çağrılan koda) birinin yaptığı her şeyi kesmesini istediğini işaret eder. Daha sonra, iş parçacığının işlemeyi güzel bir şekilde durdurması ve geri dönmesi gerekir, tıpkı olması gerektiği gibi yapıldı (ve bu noktada, iş parçacığı içeriği de atılır). OTOH, gerçekten ipliği durdurmaya zorlasaydınız, sorunuz gerçekten iyi olurdu ve cevap tanımsızdı.
Fredrik

64

Java'da iş parçacıkları öldürülmez, ancak bir iş parçacığının durdurulması işbirlikçi bir şekilde yapılır . İş parçacığının sonlandırılması istenir ve iş parçacığı daha sonra düzgün bir şekilde kapanabilir.

Genellikle bir volatile boolean , ilgili değere ayarlandığında dişin periyodik olarak kontrol ettiği ve sonlandığı alan kullanılır.

Ben bir iş parçacığı sonlanması gerektiğini kontrol etmek için kullanmak olmaz . Eğer kullanırsanız bir saha düzenleyici olarak, bu güvenilir çalışacaktır, ancak kod yerine içeride başka engelleme yöntemleri kullanır için, daha karmaşık hale gelirse döngü, kod edeceğini, meydana gelebilecek sonlandırmak değil hiç ya da en azından daha uzun sürer senin kadar belki ister.booleanvolatilewhile

Belirli engelleme kitaplığı yöntemleri kesintiyi destekler.

Her iş parçacığının zaten bir boole bayrağı kesilmiş durumu vardır ve bundan yararlanmalısınız. Bu şekilde uygulanabilir:

public void run() {
   try {
      while (!interrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }
}

public void cancel() { interrupt(); }

Uygulamada Java Concurrency'dan uyarlanan kaynak kodu . cancel()Yöntem herkese açık olduğundan, başka bir iş parçacığının bu yöntemi istediğiniz gibi çağırmasına izin verebilirsiniz.


Güvenilmeyen kodu bir eklenti veya komut dosyası olarak çalıştırırsanız ne yapmalısınız? Java, güvenilmeyen kod için katıştırılmış sanal alana sahiptir. Ve bu kum havuzu işe yaramaz, zorla durmadan çalışmaya izin verir. Java'da bir tarayıcı yazdığınızı düşünün. Rasgele sayfa komut dosyasını öldürebilme paha biçilemez.
ayvango

@ayvango O komut dosyasını kendi korumalı alanınızda çalıştırmanız gerekir. Java korumalı alanı, uygulamanın parçalarını değil, makineyi uygulamadan korur.
David Schwartz

@DavidSchwartz, java'dan sonra başka bir platform kullanmam gerektiğini mi söylüyorsun?
ayvango

@ayvango Makineyi uygulamanızdan korumak için yine de Java korumasını kullanabilirsiniz. Ancak uygulamanızın bazı bölümlerini uygulamanızın diğer bölümlerinden korumak istiyorsanız, bunu yapabilen bir araç seçmeniz gerekir.
David Schwartz

@DavidSchwartz ASFAIK bu tür araçlar, platform düzeyinde desteklenmiyorsa var olamaz. Ama tabii ki görev tamamen yorumlanmış komut dosyası motoru ile çözülebilir. Erlang gibi indirimleri sayabilir ve başka şeyler yapabilir.
ayvango

20

Bunun bir yolu, bir sınıf değişkeni ayarlamak ve onu bir sentinel olarak kullanmaktır.

Class Outer {
    public static volatile flag = true;

    Outer() {
        new Test().start();
    }
    class Test extends Thread {

        public void run() {
            while (Outer.flag) {
                //do stuff here
            }
        }
    }

}

Harici bir sınıf değişkeni ayarlayın, yani yukarıdaki örnekte flag = true. İş parçacığını 'öldürmek' için false olarak ayarlayın.


2
Tıpkı bir yan ipucu gibi: Bayrak gibi bir değişken yalnızca iş parçacığı çalıştığında ve sıkışmamışken çalışır. Thread.interrupt (), iş parçacığını çoğu bekleme koşulundan (bekleme, uyku, ağ okuma vb.) Kurtarmalıdır. Bu nedenle, bu işi yapmak için hiçbir zaman InterruptedException'ı yakalamamalısınız.
RENES

12
Bu güvenilir değil; volatileher yerde düzgün çalışmasını sağlamak için "bayrak" yapın. İç sınıf statik değildir, bu nedenle bayrak bir örnek değişkeni olmalıdır. Diğer işlemlerin (kesme gibi) yapılabilmesi için bayrak bir erişimci yönteminde temizlenmelidir. "Bayrak" adı açıklayıcı değil.
erickson

2
Ben run yöntemi "while" şey alamadım. Bu, run yönteminde yazılanların tekrarlanacağı anlamına gelmiyor mu? Bu iş parçacığının ilk etapta yapmasını istediğimiz bir şey değil :(

2
+1 yaparken (! Thread.currentThread (). İsInteruppted ()) tercih edilir
Toby

2
Her iki durumda da başarısız olur, örneğin {// open ext process} sırasında harici bir işlem açtığınızda ve bu işlem askıda kaldığında, şimdi ne iş parçacığı kesilir ne de Boolean durumunuzu kontrol etmek için sona ulaşır ve siz asılı asılı ... java.exec kullanarak bir python konsolu başlatın ve çıkış yazmadan kontrolü geri almayı deneyin ve bu işlemi öldürmek ve çıkmak için bir yol olup olmadığını görmek için deneyin .... Bu durumdan kurtulun ...
Space Rocker

11

Bunu yapmanın bir yolu var. Ancak kullanmak zorundaysanız, ya kötü bir programcısınız ya da kötü programcılar tarafından yazılmış bir kod kullanıyorsunuz. Bu nedenle, kötü bir programcı olmayı bırakmayı veya bu kötü kodu kullanarak durdurmayı düşünmelisiniz. Bu çözüm yalnızca BAŞKA YOLLU OLMAYAN durumlar içindir.

Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );

2
Bunu yapmak için hiçbir neden yoktur, çünkü Thread.stopkullanımdan kaldırılsa bile halkı aramak hala mümkündür .
Lii

1
@Lii Thread.stopde aynısını yapar, ancak erişimi ve izinleri de denetler. Kullanımı Thread.stopoldukça açık ve Thread.stop0bunun yerine neden kullandığımı hatırlamıyorum . Belki Thread.stopbenim özel durumumda işe yaramadı (Java 6'da Weblogic). Ya da belki Thread.stopde kullanımdan kaldırılmıştır ve uyarıya neden olur.
VadimPlatonov

1
Benim senaryomda bu sonsuz çalışan iş parçacığı durdurmak için tek yol oldu. Bazı Sebep için .stop () iş parçacığını durdurmadı, ancak stop0 () yaptım
fiffy

10

Biriken yorumlara dayanarak birkaç gözlem eklemek istiyorum.

  1. Thread.stop() güvenlik yöneticisi izin verirse bir iş parçacığını durduracaktır.
  2. Thread.stop()tehlikeli. Bir JEE ortamında çalışıyorsanız ve çağıran kod üzerinde herhangi bir kontrole sahip değilseniz, gerekli olabilir; bkz Thread.stop kullanımdan kaldırıldı Neden?
  3. Bir konteyner işçisi iş parçacığını asla durdurmamalısınız. Askıya alma eğiliminde olan kodu çalıştırmak istiyorsanız, (dikkatli bir şekilde) yeni bir arka plan programı iş parçacığı başlatın ve izleyin, gerekirse öldürün.
  4. stop()çağıran evrede yeni bir ThreadDeathErrorhata oluşturur ve bu hatayı hedef evreye atar . Bu nedenle, yığın izlemesi genellikle değersizdir.
  5. JRE 6'da stop()güvenlik yöneticisine danışır ve ardından stop1()bu çağrıları arar stop0(). stop0()yerel koddur.
  6. Java 13'ten Thread.stop()itibaren henüz kaldırılmadı (ancak), ancak Thread.stop(Throwable)Java 11'de kaldırıldı. ( Posta listesi , JDK-8204243 )

8

Oy verirdim Thread.stop().

Örneğin, uzun süreli bir işleminiz var (bir ağ isteği gibi). Sözde bir yanıt bekliyorsunuz, ancak bu zaman alabilir ve kullanıcı diğer kullanıcı arayüzüne geçebilir. Bu bekleyen iş parçacığı artık a) işe yaramaz b) potansiyel bir sorun çünkü sonuç alacağı zaman, tamamen işe yaramaz ve hata sayısına yol açabilecek geri aramaları tetikler.

Tüm bunlar ve CPU yoğun olabilecek yanıt işleme yapabilir. Ve bir geliştirici olarak siz bile durduramazsınız, çünkü atamazsınızif (Thread.currentThread().isInterrupted()) tüm kodlara satır atamazsınız.

Yani bir ipliği zorla durduramama tuhaf.


Ağ işlemi zaten güvenli bir şekilde kesilebilirse, sadece iş parçacığını kesin. Ağ işlemi güvenli bir şekilde iptal edilemezse, Thread.stop()yine de güvenli bir şekilde arama yapamazsınız . Oy vermiyorsunuz Thread.stop(), güvenli bir şekilde kürtajlı hale gelmesi uzun zaman alabilecek her operasyonu gerçekleştiren herkesten isteniyorsunuz. Ve bu iyi bir fikir olabilir, ancak Thread.stop()güvenli kürtaj talep etmenin bir yolu olarak uygulamakla hiçbir ilgisi yoktur . Bunun interruptiçin zaten var .
David Schwartz

"Yani bir ipliği zorla durduramama tuhaf." - ... derinlemesine bakana kadar (Java tasarımcılarının yaptığı gibi) ve itiraz etmekten daha kötü olmayan teknik olarak uygulanabilir çözümlerin olmadığı sonucuna varın stop.
Stephen C

5

Soru oldukça belirsiz. “Bir programın bir iş parçacığının çalışmasını durdurması için nasıl yazacağımı” kastediyorsanız, diğer çeşitli yanıtlar yardımcı olacaktır. Ancak “Şu anda yeniden başlatamadığım bir sunucu ile acil durumum var ve sadece ölmek için belirli bir iş parçacığına ihtiyacım var, ne gelebilir” demek istediyseniz, izleme araçlarını eşleştirmek için bir müdahale aracına ihtiyacınız vardır jstack.

Bu amaçla jkillthread'i yarattım . Kullanım talimatlarına bakınız.


Teşekkür ederim! Tam aradığım şey!
Denis Kokorin

4

Tabii ki tamamen güvenilmeyen bir kod çalıştırdığınız bir durum var. (Kişisel olarak yüklenen komut dosyalarının Java ortamımda yürütülmesine izin vererek bunu yaptım. Evet, her yerde çalan güvenlik alarm zili var, ancak uygulamanın bir parçası.) Bu talihsiz örnekte, öncelikle senaryo yazarlarına sorarak umutlu oluyorsunuz. bir tür boolean run / don't-run sinyaline saygı göstermek. Tek iyi başarısız güvenli, iş parçacığı üzerinde durdurma yöntemini çağırmak, örneğin, biraz zaman aşımından daha uzun çalışırsa.

Ancak, bu sadece "iyi" ve mutlak değil, çünkü kod ThreadDeath hatasını (veya açıkça attığınız istisnayı) yakalayabilir ve centilmence bir iş parçacığının yapması gerektiği gibi geri alamaz. Yani, sonuçta AFAIA mutlak başarısız güvenli yoktur.


AFAIK giderek daha fazla hizmet melez hale geliyor ve kod üzerinde tam kontrole sahip olmadıkları 3. taraf kodunu (eklenti, komut dosyaları, vb.) Yürütmek için yönetilen ortamı kullanıyor, iş parçacığını tamamen almak mantıksız görünüyor. hizmet mühendisleri için, canlı ve hizmet veren bir durum, hizmet vermeyen bir durumdan (asılı (iş parçacıklarını alır) veya meşgul sonsuz döngü (çekirdeği alır) nedeniyle) sonsuza kadar daha iyi olabilir
Weipeng L

3

Bir iş parçacığını incelikle öldürmenin bir yolu yoktur.

İş parçacığını kesmeye çalışabilirsiniz, bir müşterek stratejisi, iş parçacığının kendisini durduracağını bildirmek için bir zehir hapı kullanmaktır

public class CancelSupport {
    public static class CommandExecutor implements Runnable {
            private BlockingQueue<String> queue;
            public static final String POISON_PILL  = stopnow”;
            public CommandExecutor(BlockingQueue<String> queue) {
                    this.queue=queue;
            }
            @Override
            public void run() {
                    boolean stop=false;
                    while(!stop) {
                            try {
                                    String command=queue.take();
                                    if(POISON_PILL.equals(command)) {
                                            stop=true;
                                    } else {
                                            // do command
                                            System.out.println(command);
                                    }
                            } catch (InterruptedException e) {
                                    stop=true;
                            }
                    }
                    System.out.println(“Stopping execution”);
            }

    }

}

BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);

http://anandsekar.github.io/cancel-support-for-threads/


2

Genellikle bir iş parçacığını öldürmez, durdurmaz ya da kesmezsiniz (ya da kesik olup olmadığını kontrol edersiniz ()), ancak doğal olarak sonlanmasına izin verirsiniz.

Basit. İş parçacığının etkinliğini denetlemek için run () yönteminin içindeki (uçucu) boole değişkeniyle birlikte herhangi bir döngüyü kullanabilirsiniz. Durdurmak için etkin iş parçacığından ana iş parçacığına da dönebilirsiniz.

Bu şekilde bir ipliği incelikle öldürürsün :).


1

Ani iş parçacığı sonlandırma girişimleri iyi bilinen kötü programlama uygulaması ve kötü uygulama tasarımının kanıtıdır. Çok iş parçacıklı uygulamadaki tüm iş parçacıkları açıkça ve dolaylı olarak aynı işlem durumunu paylaşır ve tutarlı kalması için birbirleriyle işbirliği yapmaya zorlanır, aksi takdirde başvurunuz gerçekten teşhis edilmesi zor olan hatalara eğilimlidir. Bu nedenle, dikkatli ve açık bir uygulama tasarımı ile bu tür bir tutarlılığın güvencesini sağlamak geliştiricinin sorumluluğundadır.

Kontrollü diş sonlandırmaları için iki ana doğru çözüm vardır:

  • Paylaşılan geçici bayrağın kullanımı
  • Thread.interrupt () ve Thread.interrupted () yöntemlerinin çiftinin kullanımı.

Ani iplik sonlandırmayla ilgili sorunların iyi ve ayrıntılı açıklaması ve kontrollü iplik sonlandırması için yanlış ve doğru çözüm örnekleri burada bulunabilir:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads


Programlar artık tek bir geliştirici tarafından yazılmadığından, genellikle iş parçacıklarını öldürmek gerekir. Bu nedenle kötü programlama olarak kabul edilemez. Linux'u öldürmeden hayal edemiyorum. İş parçacıklarını öldürememe Java hatasıdır.
Pavel Niedoba

1
Harika, Bay Doğru ... Ya üzerinde kontrol sahibi olmadığınız ve zaman aşımına uğrayan ve yürütüldüğünde her 1000-2000 kez bir kez asılabilen bazı 3. taraf kütüphanelerini çağırmanız gerekiyorsa? Kötü programlama uygulaması ha? Kullandığınız koda her zaman erişemezsiniz. Her neyse, op kendi kodunu tasarlarken akışını nasıl kontrol edeceğini değil, bir iş parçacığını nasıl öldüreceğini soruyor ...
Arturas M

Soru, muteks sahibi olan veya bazı bellek bloğu tahsis edilmiş olan veya diğer iş parçacığının beklediği bir olay veya veri üretmesi gereken bir iş parçacığını öldürdüğünüzde ne olacak? Başvurunuzun geri kalan mantığına ne olacak? Küçük ve apaçık problemlerin, yeniden üretilmesi ve araştırılması zor olan karmaşık bir soruna dönüştürülme riskiniz her zaman olacaktır. İş parçacığınızı öldürmek güvenli değildir, çünkü uygulamanızı bir dizi farklı tutarsız durumda bırakabilir. Cert.org adresindeki linke bakınız.
ZarathustrA

Belli koşullar altında tüm hesaplamanın anlamsız hale gelmesine karar verebilecek bir kontrol iplikimiz var. Gerçek işi yapan birçok farklı runnable, herhangi bir uygun yerde - ne kadar korkunç olan bazı isInterrupted () varyantı ile sıçratılmalıdır! Kontrolörün bir ThreadDeath'in görünüşte hiçbir yerden çıkmasına neden olmaması, tüm senkronize edilmiş ve son olarak blokları temiz bir şekilde çözmesi çok daha hoştur. Herkes bunun hataya açık olduğunu söylüyor, ancak oldukça ilgisiz Konular için nedenini anlamıyorum.
Daniel


1

Android'de çalışmak için kesinti alamadım, bu yüzden bu yöntemi kullandım, mükemmel çalışıyor:

boolean shouldCheckUpdates = true;

private void startupCheckForUpdatesEveryFewSeconds() {
    Thread t = new Thread(new CheckUpdates());
    t.start();
}

private class CheckUpdates implements Runnable{
    public void run() {
        while (shouldCheckUpdates){
            //Thread sleep 3 seconds
            System.out.println("Do your thing here");
        }
    }
}

 public void stop(){
        shouldCheckUpdates = false;
 }

2
derleyici iş parçacığı yerel depolama ile optimize ederse, voCecent anahtar kelime shouldCheckUpdates eklenmelidir.
clinux

1

'Bir iş parçacığını öldürmek' kullanılacak doğru ifade değildir. İşte irade üzerinde iş parçacığının zarif tamamlama / çıkış uygulamak bir yolu:

Çalıştırdığım runnable:

class TaskThread implements Runnable {

    boolean shouldStop;

    public TaskThread(boolean shouldStop) {
        this.shouldStop = shouldStop;
    }

    @Override
    public void run() {

        System.out.println("Thread has started");

        while (!shouldStop) {
            // do something
        }

        System.out.println("Thread has ended");

    }

    public void stop() {
        shouldStop = true;
    }

}

Tetikleyici sınıf:

public class ThreadStop {

    public static void main(String[] args) {

        System.out.println("Start");

        // Start the thread
        TaskThread task = new TaskThread(false);
        Thread t = new Thread(task);
        t.start();

        // Stop the thread
        task.stop();

        System.out.println("End");

    }

}

derleyicinin iş parçacığı yerel depolamasıyla optimizasyon yapması durumunda, shouldStop değişkenine geçici anahtar kelime eklenmelidir.
Oleksii Kyslytsyn

0

Thread.stop kullanımdan kaldırıldı, bu yüzden java'da bir iş parçacığını nasıl durdurabiliriz?

İptal isteğinde bulunmak için her zaman kesme yöntemini ve geleceği kullanın

  1. Görev kesme sinyaline yanıt verdiğinde, örneğin, engelleme kuyruğu alma yöntemi.
Callable < String > callable = new Callable < String > () {
    @Override
    public String call() throws Exception {
        String result = "";
        try {
            //assume below take method is blocked as no work is produced.
            result = queue.take();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return result;
    }
};
Future future = executor.submit(callable);
try {
    String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
    logger.error("Thread timedout!");
    return "";
} finally {
    //this will call interrupt on queue which will abort the operation.
    //if it completes before time out, it has no side effects
    future.cancel(true);
}
  1. Görevin kesme sinyaline yanıt vermediği durumlarda, görevin kesme sinyaline yanıt vermeyen soket G / Ç gerçekleştirdiğini ve bu nedenle yukarıdaki yaklaşımı kullanmanın görevi iptal edemeyeceğini, gelecek zaman aşımına uğrayacak, ancak sonunda blokta iptal etmenin hiçbir etkisi olmayacaktır. , iş parçacığı soketi dinlemeye devam edecektir. Havuz tarafından uygulandığında soketi kapatabilir veya bağlantıda kapatma yöntemini çağırabiliriz.
public interface CustomCallable < T > extends Callable < T > {
    void cancel();
    RunnableFuture < T > newTask();
}

public class CustomExecutorPool extends ThreadPoolExecutor {
    protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
        if (callable instanceof CancellableTask)
            return ((CancellableTask < T > ) callable).newTask();
        else
            return super.newTaskFor(callable);
    }
}

public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
    public synchronized void cancel() {
        try {
            obj.close();
        } catch (IOException e) {
            logger.error("io exception", e);
        }
    }

    public RunnableFuture < T > newTask() {
        return new FutureTask < T > (this) {
            public boolean cancel(boolean mayInterruptIfRunning) {
                try {
                    this.cancel();
                } finally {
                    return super.cancel(mayInterruptIfRunning);
                }
            }

        };
    }
}
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.