जावा में शटडाउन हुक का उपयोगी उदाहरण?


126

मैं यह सुनिश्चित करने की कोशिश कर रहा हूं कि मेरा जावा एप्लिकेशन मजबूत होने के लिए उचित कदम उठाता है, और इसके कुछ भाग को शालीनतापूर्वक बंद करना शामिल है। मैं शटडाउन हुक के बारे में पढ़ रहा हूं और मुझे वास्तव में अभ्यास में उनका उपयोग करने का तरीका नहीं मिला।

वहाँ एक व्यावहारिक उदाहरण है?

मान लीजिए कि मेरे पास इस तरह का एक बहुत ही सरल अनुप्रयोग था, जो 100 के बैचों में एक फाइल, 10 से एक लाइन पर संख्याओं को लिखता है, और मैं यह सुनिश्चित करना चाहता हूं कि यदि प्रोग्राम बाधित है, तो एक दिया हुआ बैच खत्म हो जाए। मुझे शटडाउन हुक को पंजीकृत करने का तरीका मिलता है लेकिन मुझे नहीं पता कि मुझे अपने आवेदन में कैसे एकीकृत करना है। कोई सुझाव?

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();
        }
    }
}

यह भी देखें stackoverflow.com/questions/8722826/...
flow2k

जवाबों:


160

आप निम्नलिखित कर सकते हैं:

  • शटडाउन हुक को कुछ एटॉमिकबुलियन (या वाष्पशील बूलियन) "झूठ रखने" के लिए सेट करें
  • (वैकल्पिक रूप से, .interruptवर्किंग थ्रेड्स यदि वे कुछ ब्लॉकिंग कॉल में डेटा की प्रतीक्षा करते हैं)
  • कार्य सूत्र पर विधि को writeBatchकॉल करके, समाप्त होने वाले थ्रेड्स ( आपके मामले में निष्पादित ) के लिए प्रतीक्षा करें Thread.join()
  • कार्यक्रम को समाप्त करें

कुछ स्केच कोड:

  • एक जोड़ें static volatile boolean keepRunning = true;
  • में रन () आप के लिए बदल

    for (int i = 0; i < N && keepRunning; ++i)
        writeBatch(pw, i);
  • में मुख्य () आप जोड़ना:

    final Thread mainThread = Thread.currentThread();
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            keepRunning = false;
            mainThread.join();
        }
    });

यह मोटे तौर पर है कि मैं टर्मिनल में कंट्रोल-सी मारते हुए सभी ग्राहकों को कैसे एक सुंदर "अस्वीकार करता हूं"।


से डॉक्स :

जब वर्चुअल मशीन अपना शटडाउन क्रम शुरू करती है तो यह सभी पंजीकृत शटडाउन हुक को किसी अनिर्दिष्ट क्रम में शुरू करेगी और उन्हें समवर्ती रूप से चलने देगी। जब सभी हुक समाप्त हो गए हैं तो यह सभी बिन बुलाए अंतिम रूप से चलेगा यदि अंतिम रूप से बाहर निकलने में सक्षम हो गया है। अंत में, वर्चुअल मशीन रुक जाएगी।

यही है, एक शटडाउन हुक तब तक जेवीएम को चालू रखता है जब तक हुक समाप्त नहीं हो जाता है ( रन से लौटा हुआ ) ( -मिथोड )


14
आह - तो अगर मैं सही समझता हूं, तो आप जो कह रहे हैं उसका सार यह है कि शटडाउन हुक में अन्य वर्तमान में चल रहे थ्रेड्स के साथ संवाद करने और वीएम शटडाउन को बंद करने का अवसर है (जैसे थ्रेड.जॉइन का उपयोग करके) ) जब तक यह संतुष्ट नहीं हो जाता है कि एक त्वरित सफाई पूरी हो गई है। यही बात मुझे याद आ रही थी। धन्यवाद!
जेसन एस

2
हाँ। आपको यह मिला। डॉक्स से कुछ वाक्यों के साथ उत्तर को अपडेट करें।
aioobe

1
अग्रिम में क्षमा करें, लेकिन ग्रेसफुल शटडाउनटेस्ट 1 रनवेबल को लागू नहीं करना चाहिए?
विक्टर

क्या यह भी काम करेगा एक GUI मुख्य धागे में शुरू किया गया था? मुझे पता है कि यह करने का सबसे अच्छा तरीका नहीं है (इसके बजाय EDT का उपयोग करें), लेकिन मैं पुराने कोड पर काम कर रहा हूं।
अगस्टिनो

1
@ MartynasJusevičius, JVM समाप्त हो जाता है जब सभी गैर-डेमन थ्रेड्स समाप्त हो जाते हैं। यदि mainThreadडेमन थ्रेड है, तो joinहम गारंटी देते हैं कि हम इसका इंतजार करते हैं ताकि जेवीएम बंद हो जाए।
एरियोब

-9

शटडाउन हुक अनस्टर्ड थ्रेड हैं जो Runtime.addShutdownHook () के साथ पंजीकृत हैं। जेवीएम उस आदेश पर कोई गारंटी नहीं देता है जिसमें शटडाउन हुक शुरू किए जाते हैं। अधिक जानकारी के लिए देखें http://texto-terminal.blogspot.in/2015/08 /shutdown-hooks.html

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.