এক্সিকিউটর সার্ভিসের জমা এবং এক্সিকিউটর সার্ভিসের এক্সিকিউটের মধ্যে নির্বাচন করুন


194

যদি ফেরত মানটি আমার উদ্বেগ না হয় তবে আমি এক্সিকিউটর সার্ভিসের জমা দেওয়ার বা সম্পাদনের মধ্যে কীভাবে নির্বাচন করব?

যদি আমি উভয়কেই পরীক্ষা করে দেখি তবে প্রত্যাশিত মান ব্যতীত আমি উভয়ের মধ্যে কোনও পার্থক্য দেখতে পেলাম না।

ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.execute(new Task());

ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.submit(new Task());

উত্তর:


204

ব্যতিক্রম / ত্রুটি পরিচালনার বিষয়ে একটি পার্থক্য রয়েছে।

সঙ্গে সারিবদ্ধ একটি টাস্ক execute()যে কিছু উৎপন্ন Throwableহতে হবে UncaughtExceptionHandlerজন্য Threadটাস্ক চলমান প্রার্থনা করা হবে। ডিফল্ট UncaughtExceptionHandler, যা সাধারণত Throwableস্ট্যাকের ট্রেস মুদ্রণ করে System.err, কোনও কাস্টম হ্যান্ডলার ইনস্টল না করা থাকলে তা শুরু করা হবে।

অন্যদিকে, একটি Throwableএকটি টাস্ক দ্বারা উত্পন্ন সঙ্গে সারিবদ্ধ submit()ইচ্ছা বেঁধে Throwableকরার Futureযে কল থেকে উত্পাদিত হয় submit()। কল করা হচ্ছে get()যে Futureএকটি নিক্ষেপ করা হবে ExecutionExceptionমূল সঙ্গে Throwable(কল করে প্রবেশযোগ্য এর কারণ হিসাবে getCause()উপর ExecutionException)।


19
লক্ষ্য করুন এই আচরণ যেমন থাকুক বা না থাকুক আপনার উপর নির্ভরশীল নিশ্চিত করা হয় না Runnableএকটি আবৃত পরার Taskবা না হয়, আপনি উপর কোন নিয়ন্ত্রণ আছে হতে পারে। উদাহরণস্বরূপ, যদি আপনি Executorপ্রকৃতপক্ষে একটি হন তবে ScheduledExecutorServiceআপনার কার্য অভ্যন্তরীণভাবে Futureএকটিতে আবৃত Throwableহবে এবং অবহিত গুলি এই বস্তুর সাথে আবদ্ধ থাকবে।
rxg

4
আমি অবশ্যই 'একটি Futureনা জড়ানো ' অবশ্যই, মানে । উদাহরণস্বরূপ, শিডিউলথ্রেডপুলএক্সেকিউটারের # এক্সিকিউটের জাভাডোক দেখুন ।
আরএক্সজি

60

এক্সিকিউট করুন : আগুনের জন্য এটি ব্যবহার করুন এবং কলগুলি ভুলে যান

জমা দিন : পদ্ধতি কলের ফলাফল পরিদর্শন করতে এবং কলFutureদ্বারা প্রত্যাখ্যানকরাআপত্তিরউপর যথাযথ ব্যবস্থা গ্রহণের জন্যএটি ব্যবহার করুন

জাভাদোকস থেকে

submit(Callable<T> task)

মৃত্যুদন্ড কার্যকর করার জন্য একটি মূল্য-ফিরিয়ে দেওয়া টাস্ক জমা দেয় এবং কার্যের মুলতুবি থাকা ফলাফলগুলি উপস্থাপন করে একটি ভবিষ্যত প্রদান করে।

Future<?> submit(Runnable task)

মৃত্যুদন্ড কার্যকর করার জন্য একটি রান্নেবল টাস্ক জমা দেয় এবং সেই টাস্কের প্রতিনিধিত্ব করে ভবিষ্যত প্রদান করে।

void execute(Runnable command)

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

ব্যবহার করার সময় আপনাকে অবশ্যই সাবধানতা অবলম্বন করতে হবে submit()। আপনি যদি try{} catch{}ব্লগে আপনার টাস্ক কোড এম্বেড না করেন তবে এটি ফ্রেমওয়ার্কটিতেই ব্যতিক্রম লুকায় ।

উদাহরণ কোড: এই কোডটি গ্রাস করে Arithmetic exception : / by zero

import java.util.concurrent.*;
import java.util.*;

public class ExecuteSubmitDemo{
    public ExecuteSubmitDemo()
    {
        System.out.println("creating service");
        ExecutorService service = Executors.newFixedThreadPool(10);
        //ExtendedExecutor service = new ExtendedExecutor();
        service.submit(new Runnable(){
                 public void run(){
                    int a=4, b = 0;
                    System.out.println("a and b="+a+":"+b);
                    System.out.println("a/b:"+(a/b));
                    System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName());
                 }
            });
        service.shutdown();
    }
    public static void main(String args[]){
        ExecuteSubmitDemo demo = new ExecuteSubmitDemo();
    }
}

আউটপুট:

java ExecuteSubmitDemo
creating service
a and b=4:0

একই কোড প্রতিস্থাপন ছোঁড়ার submit()সঙ্গে execute():

প্রতিস্থাপন করা

service.submit(new Runnable(){

সঙ্গে

service.execute(new Runnable(){

আউটপুট:

java ExecuteSubmitDemo
creating service
a and b=4:0
Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
        at ExecuteSubmitDemo$1.run(ExecuteSubmitDemo.java:14)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)

সাবমিট () ব্যবহার করার সময় এই জাতীয় পরিস্থিতিগুলি কীভাবে পরিচালনা করবেন?

  1. Tas} ক্যাচ Embed} ব্লক কোড দিয়ে আপনার টাস্ক কোড ( হয় চলমান বা কলযোগ্য প্রয়োগকরণ) এম্বেড করুন
  2. বাস্তবায়ন CustomThreadPoolExecutor

নতুন সমাধান:

import java.util.concurrent.*;
import java.util.*;

public class ExecuteSubmitDemo{
    public ExecuteSubmitDemo()
    {
        System.out.println("creating service");
        //ExecutorService service = Executors.newFixedThreadPool(10);
        ExtendedExecutor service = new ExtendedExecutor();
        service.submit(new Runnable(){
                 public void run(){
                    int a=4, b = 0;
                    System.out.println("a and b="+a+":"+b);
                    System.out.println("a/b:"+(a/b));
                    System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName());
                 }
            });
        service.shutdown();
    }
    public static void main(String args[]){
        ExecuteSubmitDemo demo = new ExecuteSubmitDemo();
    }
}

class ExtendedExecutor extends ThreadPoolExecutor {

   public ExtendedExecutor() { 
       super(1,1,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(100));
   }
   // ...
   protected void afterExecute(Runnable r, Throwable t) {
     super.afterExecute(r, t);
     if (t == null && r instanceof Future<?>) {
       try {
         Object result = ((Future<?>) r).get();
       } catch (CancellationException ce) {
           t = ce;
       } catch (ExecutionException ee) {
           t = ee.getCause();
       } catch (InterruptedException ie) {
           Thread.currentThread().interrupt(); // ignore/reset
       }
     }
     if (t != null)
       System.out.println(t);
   }
 }

আউটপুট:

java ExecuteSubmitDemo
creating service
a and b=4:0
java.lang.ArithmeticException: / by zero

ভাল খাস্তা ব্যাখ্যা। যদিও এটি প্রসারিত করা সত্যই প্রয়োজন হয় না। টাস্কটি সাফল্য ছিল কি না তা জানতে কেবল ভবিষ্যতের অবজেক্টটি গ্রাস করতে হবে। সুতরাং, আপনি যদি ভবিষ্যত গ্রাস করার পরিকল্পনা করছেন তবে জমা দিন () ব্যবহার করুন <t> অন্যথায় কেবল এক্সিকিউট () ব্যবহার করুন
16:58 এ প্রেশ

11

আপনি যদি রিটার্নের ধরণের বিষয়ে যত্নশীল না হন তবে এক্সিকিউটটি ব্যবহার করুন। ভবিষ্যতের প্রত্যাবর্তন ছাড়াই এটি জমা দেওয়ার মতোই।


15
গৃহীত উত্তর অনুযায়ী এটি সঠিক নয়। ব্যতিক্রম হ্যান্ডলিং একটি বেশ তাৎপর্যপূর্ণ পার্থক্য।
জিরো 3

7

জাভাদোক থেকে নেওয়া:

পদ্ধতিটি একটি {@ লিঙ্ক ফিউচার creating তৈরি এবং ফিরে দিয়ে submitবেস পদ্ধতিটি l @ লিঙ্ক এক্সিকিউটার # base প্রসারিত করে executeযা কার্যকরকরণ বাতিল করতে এবং / অথবা সমাপ্তির জন্য অপেক্ষা করতে ব্যবহৃত হতে পারে।

ব্যক্তিগতভাবে আমি মৃত্যুদন্ডের ব্যবহার পছন্দ করি কারণ এটি আরও ঘোষিত বোধ করে, যদিও এটি সত্যই ব্যক্তিগত পছন্দের বিষয়।

আরও তথ্য দেওয়ার জন্য: ExecutorServiceবাস্তবায়নের ক্ষেত্রে, কলটি প্রয়োগ করে মূল বাস্তবায়নটি Executors.newSingleThreadedExecutor()হ'ল একটি ThreadPoolExecutor

submitকল তার পিতা বা মাতা দ্বারা উপলব্ধ করা হয় AbstractExecutorServiceএবং সমস্ত কল অভ্যন্তরীণভাবে চালানো। এক্সিকিউটটি ওভাররাইড / ThreadPoolExecutorসরাসরি দ্বারা সরবরাহ করা হয় ।


2

জাভাডোক থেকে :

কমান্ডটি এক্সিকিউটার বাস্তবায়নের বিবেচনার ভিত্তিতে একটি নতুন থ্রেডে, কোনও পুলড থ্রেডে বা কলিং থ্রেডে কার্যকর করতে পারে।

সুতরাং বাস্তবায়নের উপর নির্ভর করে Executorআপনি দেখতে পাবেন যে টাস্কটি সম্পাদন করার সময় জমা দেওয়ার থ্রেড ব্লক করে।


1

পুরো উত্তরটি এখানে দুটি প্রকাশিত উত্তরগুলির সংকলন (আরও কিছুটা "অতিরিক্ত"):

  • কোনও কার্য জমা দেওয়ার মাধ্যমে (বনাম এটি কার্যকর করে) আপনি ভবিষ্যত ফিরে পাবেন যা ফলাফল পেতে বা ক্রিয়াটি বাতিল করতে ব্যবহার করা যেতে পারে। আপনি যখন এই ধরণের নিয়ন্ত্রণ রাখেন না execute(কারণ এটির রিটার্ন টাইপ আইডি void)
  • executeপ্রত্যাশিত কিছু Runnableসময় submitহতে পারে একটি Runnableবা Callableএকটিকে তর্ক হিসাবে গ্রহণ করতে পারে (দুজনের মধ্যে পার্থক্য সম্পর্কে আরও তথ্যের জন্য - নীচে দেখুন)।
  • executeভবিষ্যতে যে কোনও ধরণের ব্যতিক্রমকে submitআবদ্ধ করে দেয় যা ফলস্বরূপ ফিরে আসে এবং কেবল যখন আপনি (মোড়ানো) ব্যতিক্রম কল করবেন তখনই কোনও চেক করা-ব্যতিক্রমগুলি সরাসরি তাড়াতাড়ি বুদবুদগুলি আপ করুন (যখন এটি চেক ব্যতিক্রমগুলি ছুঁড়ে ফেলতে পারে না !!!) and future.get()আপনি যে থ্রোবেল পাবেন সেটি হ'ল একটি উদাহরণ ExecutionExceptionএবং আপনি যদি এই বস্তুর কল করেন তবে getCause()এটি আসল থ্রোবেলকে ফিরিয়ে দেবে।

আরও কয়েকটি (সম্পর্কিত) বিষয়:

  • এমনকি যদি আপনি যে কাজটি করতে চান তা submitফলাফল ফেরতের প্রয়োজন না হলেও আপনি এখনও Callable<Void>(একটি ব্যবহারের পরিবর্তে Runnable) ব্যবহার করতে পারেন ।
  • বাধা ব্যবস্থার সাহায্যে কাজ বাতিল করা যেতে পারে । এখানে বাতিল নীতি কীভাবে প্রয়োগ করা যায় তার একটি উদাহরণ

সংক্ষেপে, এটি (বনাম । ক ) এর সাথে ব্যবহার করা submitআরও ভাল অনুশীলন । এবং আমি "অনুশীলনে জাভা চুক্তি" থেকে উদ্ধৃত করব ব্রায়ান গয়েটস দ্বারা:CallableexecuteRunnable

.3.৩.২ ফলাফল বহনকারী কার্য: কলযোগ্য এবং ভবিষ্যত

এক্সিকিউটার কাঠামোটি রান্নেবলকে তার প্রাথমিক কাজ উপস্থাপন হিসাবে ব্যবহার করে। চলমান একটি মোটামুটি সীমাবদ্ধ বিমূর্ততা; রান কোনও মান ফিরিয়ে দিতে বা চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে না, যদিও এটির কোনও লগ ফাইলে লিখতে বা ভাগ করে নেওয়া ডেটা কাঠামোর ফলস্বরূপ রাখার মতো পার্শ্ব প্রতিক্রিয়া থাকতে পারে। অনেক কাজ কার্যকরভাবে পিছিয়ে যাওয়া গণনা হয় a একটি ডাটাবেস ক্যোয়ারী কার্যকর করা, নেটওয়ার্কের মাধ্যমে কোনও উত্স আনা, বা কোনও জটিল ফাংশন গণনা করা। এই ধরণের কাজের জন্য, কলযোগ্য একটি ভাল বিমূর্ততা: এটি প্রত্যাশা করে যে মূল এন্ট্রি পয়েন্ট, কল, একটি মান ফিরে আসবে এবং প্রত্যাশা করে যে এটি একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারে .7.7 এক্সিকিউটাররা রান্নেবল সহ অন্যান্য ধরণের কাজগুলিকে মোড়ানোর জন্য বিভিন্ন ইউটিলিটি পদ্ধতি অন্তর্ভুক্ত করে includes এবং জাভা.সিকিউরিটি ri প্রাইভিলিজড অ্যাকশন, একটি কলযোগ্য with


1

কেবলমাত্র গৃহীত উত্তরটিতে যোগ করা-

তবে, কার্যগুলি থেকে বাদ দেওয়া ব্যতিক্রমগুলি কেবলমাত্র মৃত্যুদন্ড কার্যকর () সহ জমা দেওয়া টাস্কগুলির জন্য অবিচ্ছিন্ন ব্যতিক্রম হ্যান্ডলারে পরিণত করে; এক্সিকিউটর সার্ভিসে জমা () সহ জমা দেওয়া কার্যগুলির জন্য, কোনও নিক্ষিপ্ত ব্যতিক্রমকে কার্যের রিটার্ন স্ট্যাটাসের অংশ হিসাবে বিবেচনা করা হয়।

উৎস

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