2010-05-27 14 views
105

Java uygulamamın sağlam olması için makul adımlar attığından emin olmaya çalışıyorum ve bunun bir kısmı incelikle kapatmayı içeriyor. Ben shutdown hooks hakkında okuyorum ve aslında bunları pratikte nasıl kullanacağımı anlamıyorum.Java'da bir kapatma kancası için yararlı bir örnek?

Pratik bir örnek var mı?

Diyelim ki, aşağıdaki gibi basit bir uygulama olduğunu söyleyebilirim. Bu sayı, bir dosyaya 10, bir satıra, 100 yığın halinde yazıyor ve program kesilirse belirli bir toplu işin tamamlandığından emin olmak istiyorum. Bir kapatma kancasının nasıl kaydedileceğine bakıyorum ama bunu uygulamaya nasıl entegre edeceğime dair hiçbir fikrim yok. Baska öneri?

package com.example.test.concurrency; 

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.PrintWriter; 

public class GracefulShutdownTest1 { 
    final private int N; 
    final private File f; 
    public GracefulShutdownTest1(File f, int N) { this.f=f; this.N = N; } 

    public void run() 
    { 
     PrintWriter pw = null; 
     try { 
      FileOutputStream fos = new FileOutputStream(this.f); 
      pw = new PrintWriter(fos); 
      for (int i = 0; i < N; ++i) 
       writeBatch(pw, i); 
     } 
     catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      pw.close(); 
     }  
    } 

    private void writeBatch(PrintWriter pw, int i) { 
     for (int j = 0; j < 100; ++j) 
     { 
      int k = i*100+j; 
      pw.write(Integer.toString(k)); 
      if ((j+1)%10 == 0) 
       pw.write('\n'); 
      else 
       pw.write(' '); 
     } 
    } 

    static public void main(String[] args) 
    { 
     if (args.length < 2) 
     { 
      System.out.println("args = [file] [N] " 
        +"where file = output filename, N=batch count"); 
     } 
     else 
     { 
      new GracefulShutdownTest1(
        new File(args[0]), 
        Integer.parseInt(args[1]) 
      ).run(); 
     } 
    } 
} 

cevap

134

Aşağıdaki yapabilirdi:

  • yanlış
  • (İsteğe bağlı kapatma bazı AtomicBoolean set kancayı (veya uçucu boolean) "keepRunning" Let .interrupt çalışma ipler onlar beklersek Bazı engelleme çağrılarında veriler)
  • Çalışmakta olan iş parçacığı üzerinde Thread.join() yöntemini çağırarak, iş parçacığı için (işinize writeBatch yürütme) bekleyin.

Bazı kabataslak kod programı sonlandırın:

  • ) (a static volatile boolean keepRunning = true;
  • yılında koşmak ekle Eğer ana olarak

    for (int i = 0; i < N && keepRunning; ++i) 
        writeBatch(pw, i); 
    
  • değiştirmek () Eklemek:

    Ben zarif yapmak terminalde "Control-C isabet sonra tüm müşterilerine reddetme" nasıl kabaca var
    final Thread mainThread = Thread.currentThread(); 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
        public void run() { 
         keepRunning = false; 
         mainThread.join(); 
        } 
    }); 
    

. the docs itibaren


: sanal makine kendi kapatma dizisi başladığında

bazı belirtilmemiş sırayla tüm kayıtlı kapatma kanca başlatmak ve onları aynı anda çalışmasına izin edecektir. Tüm kancalar bittiğinde, çıkışta sonlandırma etkinleştirildiyse, tüm müdahale edilmemiş sonleştiricileri çalıştırır. Son olarak, sanal makine durur. olduğu

, bir kapatma kanca JVM kanca sona kadar (çalıştırmak dönen çalışmasını sağlar() kullanılan yöntem.

+11

Ah - eğer doğru anlıyorsam, söylediklerinizin özü, kapatma kanadının şu anda çalışan diğer iş parçacıkları ile iletişim kurma ve VM kapatma özelliğini devre dışı bırakması için bir fırsat olmasıdır. Örneğin, hızlı bir temizleme işleminin tamamlandığından emin oluncaya kadar Thread.join() öğesini kullanarak. Kaybettiğim nokta bu. Teşekkürler! –

+1

Evet. Anladın. Yanıtı, dokümanlardan birkaç cümle ile güncellendi. – aioobe

+1

Üzgünüz, ama GracefulShutdownTest1 Runnable'ı uygulamamalı mı? – Victor

İlgili konular