সবসময় একটি অবরুদ্ধ ব্লক চালানো হয়?


112

এমন কোনও শর্ত আছে যেখানে অবশেষে জাভাতে চলতে পারে না? ধন্যবাদ।


13
কোনও নির্দিষ্ট নামী প্রতিষ্ঠানের সাথে চাকরির চেষ্টা করার সময় আপনি কি এমন প্রশ্ন জিজ্ঞাসা করতে পারেন?
টম হাটিন -

@ টমহটিন-ট্যাকলাইন এর নাম রাখবেন? (Godশ্বর, আমি এই পোস্টটি কত পুরানো মিস করেছি!)
হেল

6
@ হেইল আমি গেমটি ছেড়ে দিতে চাই না তবে আপনি এটি গুগল করতে পারেন।
টম হাটিন -

সংক্ষিপ্ত উত্তর: হ্যাঁ, সাধারণ পরিস্থিতিতে।
হাঙ্গর

উত্তর:


139

থেকে সূর্যের টিউটোরিয়াল

দ্রষ্টব্য: চেষ্টা বা ক্যাচ কোড কার্যকর করার সময় যদি জেভিএম প্রস্থান করে, তবে অবশেষে ব্লকটি কার্যকর করতে পারে না। তেমনিভাবে, চেষ্টা চালানোর থ্রেড বা ক্যাচ কোডটি বাধাগ্রস্ত বা হত্যা করা হয়, শেষ পর্যন্ত ব্লকটি কার্যকরভাবে প্রয়োগ না করা সত্ত্বেও সামগ্রিকভাবে অ্যাপ্লিকেশনটি অব্যাহত থাকে।

অবশেষে ব্লকটি কার্যকর হবে না এমন অন্য কোনও উপায় আমি জানি না ...


6
@ দুডিলার - আমি যথেষ্ট নিশ্চিত যে "" বিদ্যুৎ ডাউন "" "যদি জেভিএম প্রস্থান করে ..." এর মধ্যে অন্তর্ভুক্ত রয়েছে:: পি
জেসন কোকো

2
@ জেসন কোকো: সমাপ্তি (বিদ্যুৎ হ্রাসের পরে) বেরিয়ে আসার মতো জিনিস নয়; দ্বিতীয়টি কমবেশি সংগঠিত প্রক্রিয়া যা শেষের দিকে শেষ হয়। ; পি
ব্যবহারকারী 359996

2
আফাইক, যদি কোনও থ্রেড বাধাগ্রস্ত হয় তবে তা অবিলম্বে থামানো হবে না। বাধা সনাক্ত করতে এবং এর কাজটি থামাতে থ্রেডের কোডের মধ্যে রয়েছে, সুতরাং শেষ পর্যন্ত কোডটি চালানো উচিত।
বার্ট ভ্যান হিউকেলোম

2
আমি অনুমান করি যে অবশেষে ব্লকে যদি কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয়, তবে ব্লকের বাকী অংশটি কার্যকর করা হয় না।
অ্যাড্রায়ান কোস্টার

ভাল যে স্তন্যপান!
ইরান

63

System.exit ভার্চুয়াল মেশিনটি বন্ধ করে দেয়।

বর্তমানে চলমান জাভা ভার্চুয়াল মেশিনটি সমাপ্ত করে। যুক্তি স্থিতি কোড হিসাবে কাজ করে; কনভেনশন দ্বারা, একটি ননজারো স্থিতি কোড অস্বাভাবিক সমাপ্তি নির্দেশ করে।

এই পদ্ধতিটি exitক্লাসে পদ্ধতিটিকে কল করে Runtime। এই পদ্ধতিটি কখনই সাধারণত ফিরে আসে না।

    try {
        System.out.println("hello");
        System.exit(0);
    }
    finally {
        System.out.println("bye");
    } // try-finally

"বাই" উপরের কোডটিতে মুদ্রণ করে না।


এছাড়াও একটি ব্যতিক্রম জাভা ভার্চুয়াল মেশিন বন্ধ করা উচিত।
কাইসুন

3
যদি System.exit (0) কার্যকর করার সময় কোনও ব্যতিক্রম ঘটে থাকে তবে অবশেষে ব্লকটি কার্যকর করা হবে।
হলি

50

অন্যরা যা বলেছে কেবল তার প্রসারিত করার জন্য, जेভিএম থেকে বেরিয়ে আসার মতো কিছু ঘটায় না এমন পরিণতি অবশেষে অবরুদ্ধ করবে। সুতরাং নিম্নলিখিত পদ্ধতি:

public static int Stupid() {
  try {
    return 0;
  }
  finally {
    return 1;
  }
}

আশ্চর্যজনকভাবে উভয়ই সংকলন করে ফিরে আসবে 1।


2
এটি আমাকে কয়েক সপ্তাহ আগে বেশ কয়েক ঘন্টা ধরে বিভ্রান্ত করেছে।
নিকফ

3
অবশেষে ব্লক থেকে কোনও মান ফেরানো খারাপ ধারণা হিসাবে বিবেচিত। হয় শুধুমাত্র চেষ্টা ব্লক থেকে ফিরে আসুন, বা চেষ্টা / শেষ অবধি ব্লকের বাইরে থেকে ফিরে আসুন। বেশিরভাগ আইডিই এটি একটি সতর্কতা সহ চিহ্নিত করবে।
রান বিরন

1
@ নিকফ আমি সংগ্রহ করেছি যে আপনি আর বিভ্রান্ত হন না। ১ টি কেন ফিরে আসে এবং ০ নয় কেন তার মেকানিক্সগুলিতে আপনি বিশদটি জানাতে পারেন? আমি কেবল অনুমান করতে পারি যে মেমরিটি (বা এটি একটি রেজিস্টার) যা ফাংশনটির রিটার্ন মান সংরক্ষণ করে যা প্রাথমিকভাবে 0 রাখে, অবশেষে ব্লকটি কার্যকর হওয়ার পরে ওভাররাইট করা হয় ।
ইয়াণিভ

2
এটি কৌতূহলী, সি # এ এটি শেষ অবধি থেকে ফিরে আসার অনুমতি নেই।
জেএমসিএফ 125

3
@ রানবিরন অবশ্যই তিনি আসলে শেষ অবধি ব্লকের ভিতরে ফিরে আসার পরামর্শ দিচ্ছিলেন না, তিনি কেবলমাত্র এটি দেখানোর চেষ্টা করছিলেন যে কোনও রিটার্নের বিবৃতি এখনও তথাকথিত ব্লকের কোড কার্যকর করতে পারে cause
অ্যাকোয়ারেল

15

System.exit- এর সাথে সম্পর্কিত, কিছু প্রকার বিপর্যয়কর ব্যর্থতা রয়েছে যেখানে একটি অবশেষে ব্লক কার্যকর নাও করতে পারে। যদি জেভিএম সম্পূর্ণরূপে স্মৃতি থেকে সরে যায় তবে এটি কেবল ধরা না দেওয়া বা শেষ অবধি ঘটতে পারে না।

বিশেষত, আমি একটি প্রকল্প মনে করি যেখানে আমরা বোকামি ব্যবহার করার চেষ্টা করেছি

catch (OutOfMemoryError oome) {
    // do stuff
}

এটি কার্যকর হয়নি কারণ ক্যাচ ব্লকটি কার্যকর করার জন্য জেভিএমের কোনও স্মৃতি নেই।


যখন আউটআফমিউরিওর নিক্ষেপ করা হয় তখন সাধারণত প্রচুর মেমরি থাকে (জিসি থ্রেশিং বন্ধ করতে)। তবে, আপনি যদি বারবার এটি ধরেন তবে আপনি অবশ্যই স্পষ্টতই জিসিকে মেরে ফেলাবেন।
টম হাটিন -

আমি ভেবেছিলাম কেউ চেক করা ব্যতিক্রম ধরা উচিত নয়!
সের্গেই শেভচাইক

1
আমি আমার দিকে চেষ্টা করেছি, jdk7 ব্যবহার করে, তবে এটি আউটঅফমোরি ত্রুটিটি ধরা পড়ে!
জেস্কি

10
try { for (;;); } finally { System.err.println("?"); }

সেক্ষেত্রে শেষ অবধি কার্যকর করা হবে না (যদি অবহেলিত না Thread.stopবলা হয় বা একটি সমতুল্য না হয়, তবে একটি সরঞ্জাম ইন্টারফেসের মাধ্যমে বলুন)।


এই পৃষ্ঠায় দাবি করা হয়েছে যে একটি থ্রেডডিথ ত্রুটি নিক্ষেপ করা হয়েছে এবং থ্রড.স্টপ () ডাকা হলে স্ট্যাকটি সাধারণত আনইন্ডাইড হয়। আমি কি ধরা পড়ছি এমন কিছু আছে? ডাউনলোড.
oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/guide/…

আমি মনে করি না একটি ধরা আছে। সম্ভবত সেখানে আপনি এমন একটি ক্যাচ কল্পনা করছেন যা সেখানে নেই। যদি আমরা একটি স্পষ্টভাবে রাখি throw, তবে finallyব্লকটি প্রত্যাশিত হিসাবে কার্যকর করা হবে। try { throw new ThreadDeath(); } finally { System.err.println("?"); }
টম হাটিন -

9

সান টিউটোরিয়ালটি এখানে এই থ্রেডে ভুলভাবে উদ্ধৃত করা হয়েছে।

দ্রষ্টব্য: চেষ্টা বা ক্যাচ কোড কার্যকর করার সময় যদি জেভিএম প্রস্থান করে, তবে অবশেষে ব্লকটি কার্যকর হবে না। তেমনিভাবে, চেষ্টা চালানোর থ্রেড বা ক্যাচ কোডটি বাধাগ্রস্ত বা হত্যা করা হয়, অবশেষে অবরুদ্ধ হবে চালানো না যদিও সামগ্রিকভাবে আবেদন চলতে থাকে।

আপনি যদি অবশেষে অবরুদ্ধ হওয়ার জন্য সূর্যের টিউটোরিয়ালটি ঘনিষ্ঠভাবে দেখে থাকেন তবে এটি "মৃত্যুদণ্ড কার্যকর করবে না" তবে "কার্যকর করা যাবে না" বলে না এটি সঠিক বর্ণনা এখানে

দ্রষ্টব্য: চেষ্টা বা ক্যাচ কোড কার্যকর করার সময় যদি জেভিএম প্রস্থান করে, তবে অবশেষে ব্লকটি কার্যকর করতে পারে না। একইভাবে, যদি থ্রেড চেষ্টা করুন বা ধরা কোড নির্বাহ বিঘ্নিত অথবা নিহত হন, পরিশেষে ব্লক পারে চালানো না যদিও সামগ্রিকভাবে আবেদন চলতে থাকে।

এই আচরণের স্পষ্ট কারণ হ'ল কল টু system.exit () একটি রানটাইম সিস্টেম থ্রেডে প্রক্রিয়াজাত হয় যা jvm বন্ধ করতে সময় নিতে পারে, এরই মধ্যে থ্রেড শিডিয়ুলার শেষ অবধি কার্যকর করতে অনুরোধ করতে পারে। সুতরাং পরিশেষে সর্বদা কার্যকর করার জন্য ডিজাইন করা হয়েছে, তবে আপনি যদি জেভিএম বন্ধ করে দিচ্ছেন, শেষ পর্যন্ত মৃত্যুদণ্ড কার্যকর হওয়ার আগে জেভিএম বন্ধ হয়ে যায়।


6

এছাড়াও যদি অচলাবস্থা / লাইভলকটি ভিতরে ঘটে try ব্লকের ।

এখানে কোডটি এটি দেখায়:

public class DeadLocker {
    private static class SampleRunnable implements Runnable {
        private String threadId;
        private Object lock1;
        private Object lock2;

        public SampleRunnable(String threadId, Object lock1, Object lock2) {
            super();
            this.threadId = threadId;
            this.lock1 = lock1;
            this.lock2 = lock2;
        }

        @Override
        public void run() {
            try {
                synchronized (lock1) {
                    System.out.println(threadId + " inside lock1");
                    Thread.sleep(1000);
                    synchronized (lock2) {
                        System.out.println(threadId + " inside lock2");
                    }
                }
            } catch (Exception e) {
            } finally {
                System.out.println("finally");
            }
        }

    }

    public static void main(String[] args) throws Exception {
        Object ob1 = new Object();
        Object ob2 = new Object();
        Thread t1 = new Thread(new SampleRunnable("t1", ob1, ob2));
        Thread t2 = new Thread(new SampleRunnable("t2", ob2, ob1));
        t1.start();
        t2.start();
    }
}

এই কোডটি নিম্নলিখিত আউটপুট উত্পাদন করে:

t1 inside lock1
t2 inside lock1

এবং "অবশেষে" কখনই মুদ্রিত হয় না


3
প্রযুক্তিগতভাবে, চেষ্টা ব্লকটি কখনই প্রস্থান করে না তাই অবশেষে ব্লকটি কখনই কার্যকর করার সুযোগ পায় না। অসীম লুপের জন্য একই কথা বলা যেতে পারে।
জেফ মার্কাডো

6

চেষ্টা বা ক্যাচ কোড কার্যকর করার সময় যদি জেভিএম প্রস্থান করে, তবে অবশেষে ব্লকটি কার্যকর করতে পারে না। ( উত্স )

সাধারণ শাটডাউন - এটি তখনই ঘটে যখন শেষ নন-ডেমন থ্রেডটি প্রস্থান হয় বা যখন রানটাইম.এক্সিট () ( উত্স ) হয়

যখন কোনও থ্রেড প্রস্থান করে, JVM চলমান থ্রেডগুলির একটি তালিকা সম্পাদন করে এবং যদি কেবলমাত্র থ্রেডগুলি অবশিষ্ট থাকে তবে এটি ডেমন থ্রেড থাকে, এটি একটি সুশৃঙ্খল শাটডাউন শুরু করে। যখন জেভিএম বন্ধ হয়ে যায়, অন্য কোনও ডেমন থ্রেডগুলি পরিত্যক্ত হয় অবশেষে ব্লকগুলি কার্যকর করা হয় না, স্ট্যাকগুলি জেভিএম কেবলমাত্র প্রস্থান করে না। ডিমন থ্রেডগুলি অল্প পরিমাণে ব্যবহার করা উচিত কয়েকটি প্রসেসিং ক্রিয়াকলাপ কোনও ক্লিনআপ ছাড়াই কোনও সময়ে নিরাপদে ছেড়ে দেওয়া যেতে পারে। বিশেষত, যে কাজগুলি যে কোনও ধরণের I / O সম্পাদন করতে পারে সেই জন্য ডেমন থ্রেডগুলি ব্যবহার করা বিপজ্জনক। ডেমন থ্রেডগুলি "গৃহকর্মী" কাজের জন্য সেরা সংরক্ষণ করা হয়, যেমন একটি পটভূমি থ্রেড যা অন্তর অন্তর মেমরির ক্যাশে থেকে মেয়াদোত্তীর্ণ এন্ট্রিগুলি সরিয়ে দেয়। ( উত্স )

সর্বশেষ নন-ডেমন থ্রেড উদাহরণ থেকে বেরিয়ে এসেছে:

public class TestDaemon {
    private static Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                while (true) {
                    System.out.println("Is alive");
                    Thread.sleep(10);
                    // throw new RuntimeException();
                }
            } catch (Throwable t) {
                t.printStackTrace();
            } finally {
                System.out.println("This will never be executed.");
            }
        }
    };

    public static void main(String[] args) throws InterruptedException {
        Thread daemon = new Thread(runnable);
        daemon.setDaemon(true);
        daemon.start();
        Thread.sleep(100);
        // daemon.stop();
        System.out.println("Last non-daemon thread exits.");
    }
}

আউটপুট:

Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive

1

নিম্নলিখিত ক্ষেত্রে, অবশেষে ব্লক কার্যকর করা হবে না: -

  • কখন ব্লক System.exit(0)থেকে tryডাকা হয়।
  • যখন জেভিএম মেমরির বাইরে চলে যায়
  • যখন আপনার জাভা প্রক্রিয়াটি কার্যনির্বাহী কার্যকারিতা বা কনসোল থেকে জোর করে হত্যা করা হয়
  • আপনার tryব্লকে ডেডলক অবস্থা
  • যখন আপনার যন্ত্রটি বিদ্যুতের ব্যর্থতার কারণে বন্ধ হয়ে যায়

এছাড়াও অন্যান্য ফ্রিঞ্জের ক্ষেত্রেও থাকতে পারে, যেখানে অবশেষে ব্লক কার্যকর করা হবে না।


1

অবশেষে কোড সম্পাদন বন্ধ করার জন্য দুটি উপায় রয়েছে:
১. System.exit () ব্যবহার করুন;
২. যদি কোনওভাবে কার্যকর করা নিয়ন্ত্রণ অবরুদ্ধ করার চেষ্টা না করে।
দেখা:

public class Main
{
  public static void main (String[]args)
  {
    if(true){
        System.out.println("will exceute");
    }else{
        try{
            System.out.println("result = "+5/0);
        }catch(ArithmeticException e){
          System.out.println("will not exceute");
        }finally{
          System.out.println("will not exceute");  
        }
    }
  }
}

0

আমি অবশেষে খেলার কাঠামোর সাথে সম্পর্কিত সম্পর্কিত সম্পাদন না করার একটি খুব নির্দিষ্ট কেস পেয়েছি।

আমি অবাক হয়ে এই কন্ট্রোলার অ্যাকশন কোডের অবশেষে অবরুদ্ধ হওয়ার পরে কেবল একটি ব্যতিক্রমের পরে ডেকেছিলাম, কিন্তু কখনই কলটি সফল হয়নি।

try {
    InputStream is = getInputStreamMethod();
    renderBinary(is, "out.zip");
catch (Exception e) {
    e.printStackTrace();
} finally {
    cleanUp();
}

সম্ভবত থ্রেডটি বন্ধ করা হয়েছে বা যখন রেন্ডারবাইনারি () বলা হয়। আমি সন্দেহ করব যে অন্যান্য রেন্ডার () কলগুলির জন্য একই জিনিস ঘটেছিল, তবে আমি এটি যাচাই করি নি।

চেষ্টা / ধরা পরে রেন্ডারবাইনারি () স্থানান্তরিত করে আমি সমস্যার সমাধান করেছি। আরও তদন্তে প্রকাশ পেয়েছে যে কন্ট্রোলার ক্রিয়াকলাপ কার্যকর হওয়ার পরে মৃত্যুদন্ড কার্যকর করা যায় এমন একটি পদ্ধতি তৈরি করার জন্য প্লেটি একটি @ ফাইনালি টিকা প্রদান করে। এখানে সতর্কতামূলক বিষয়টি হ'ল নিয়ামকের কোনও ক্রিয়াকলাপ কার্যকর করার পরে এটি ডাকা হবে, সুতরাং এটি সর্বদা ভাল পছন্দ নাও হতে পারে।


-1
//If ArithmeticException Occur Inner finally would not be executed
class Temp
{
    public static void main(String[] s)
    {
        try
        {
        int x = 10/s.length;
        System.out.println(x);
        try
            {
                int z[] = new int[s.length];
                z[10] = 1000;
            }catch(ArrayIndexOutOfBoundsException e)
            {
                System.out.println(e);
            }
         finally
        {
            System.out.println("Inner finally");
        }
        }
        catch(ArithmeticException e)
        {
            System.out.println(e);
        }
    finally 
    {
        System.out.println("Outer Finally"); 
    }

System.out.println("Remaining Code");   
}
}

ইন্ডেন্টেশনটি উন্নত করুন এবং কিছু বিশদ যুক্ত করুন।
রোমানিয়া_আজ্ঞানী

1
মৃত্যুদন্ড কার্যকর এমনকি অভ্যন্তরীণ চেষ্টা ব্লক পর্যন্ত পাবেন না, অবশ্যই অন্তর্শেষে শেষ পর্যন্ত কার্যকর করা হবে না।
অ্যান্টন আরিপভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.