জাভাতে চলমান এবং কলযোগ্য ইন্টারফেসের মধ্যে পার্থক্য


492

জাভাতে একত্রী থ্রেড ডিজাইন করার সময় Runnableএবং Callableইন্টারফেসগুলি ব্যবহারের মধ্যে পার্থক্য কী , আপনি কেন অন্যটির থেকে একটি বেছে নেবেন?


2
অতিরিক্ত আলোচনার জন্য, এই পৃষ্ঠাটি পড়ার পরে, কল কলকে রান্নেবলের চেয়ে পছন্দ করা দেখুন?
বারফুইন

উত্তর:


444

ব্যাখ্যা এখানে দেখুন ।

কলযোগ্য ইন্টারফেসটি রান্নেবলের অনুরূপ, এতে উভয়ই এমন ক্লাসগুলির জন্য ডিজাইন করা হয়েছে যার উদাহরণগুলি সম্ভবত অন্য থ্রেড দ্বারা সম্পাদিত হয়। একটি রান্নেবল, তবে ফল দেয় না এবং চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে না।


269

অ্যাপ্লিকেশন Runnableএবং এর মধ্যে পার্থক্য কি Callable। পার্থক্যটি কি কেবল রিটার্ন প্যারামিটারে উপস্থিত রয়েছে Callable?

মূলত, হ্যাঁ এই প্রশ্নের উত্তর দেখুন । এবং জাভাদোকCallable

উভয় থাকার প্রয়োজন যদি Callableসমস্ত কিছু করতে Runnableপারে?

কারন Runnable ইন্টারফেসটি যা করতে পারে তা করতে পারে নাCallable !

Runnableজাভা ০.০ থেকে প্রায় Callableছিল , তবে কেবল জাভা 1.5 তে চালু হয়েছিল ... এমন ব্যবহার-কেসগুলি Runnableসমর্থন করে না যা সমর্থন করে না। তত্ত্ব অনুসারে, জাভা দলটি Runnable.run()পদ্ধতির স্বাক্ষর পরিবর্তন করতে পারত , তবে এটি প্রাক-1.5 কোডের সাথে বাইনারি কম্প্যাটিবিলিটিটি ভেঙে ফেলত, পুরানো জাভা কোডটি নতুন জেভিএমগুলিতে স্থানান্তরিত করার সময় পুনরায় কোডিং প্রয়োজন। এটি একটি বড় নম্বর-না N জাভা পিছনের দিকে সামঞ্জস্যপূর্ণ হতে চেষ্টা করে ... এবং এটি ব্যবসায় কম্পিউটিংয়ের জন্য জাভার অন্যতম বৃহত্তম বিক্রয় পয়েন্ট।

এবং, স্পষ্টতই, এমন ব্যবহারের কেস রয়েছে যেখানে কোনও কাজের জন্য ফলাফল ফেরত দেওয়ার বা চেক করা ব্যতিক্রম নিক্ষেপের প্রয়োজন হয় না । এই ব্যবহারের ক্ষেত্রে, পদ্ধতিটি থেকে ডামি ( ) মান Runnableব্যবহার করা Callable<Void>এবং ফেরানোর চেয়ে ব্যবহার আরও সংক্ষিপ্ত ।nullcall()


9
আমি ভাবছি আপনি কোথা থেকে এই ইতিহাস পেয়েছেন? এটি খুব দরকারী।
স্পাইডারম্যান 6'14

4
@ প্র্যাশ - পুরাতন পাঠ্যপুস্তকগুলিতে প্রাথমিক তথ্যগুলি পাওয়া যাবে। সংক্ষেপে জাভার প্রথম সংস্করণটি পছন্দ করুন।
স্টিফেন সি

4
(@ প্রচার - এছাড়াও ... জাভা 1.1 এর যুগে জাভা ব্যবহার শুরু করে))
স্টিফেন সি

1
@ স্টেফেনসি যদি আমি আপনার উত্তরটি সঠিকভাবে পড়ি, আপনি Runnableপশ্চাদগম্য সামঞ্জস্যতার কারণে উপস্থিত থাকার (মূলত) পরামর্শ দিচ্ছেন । কিন্তু এমন পরিস্থিতি নেই যেখানে Callableইন্টারফেস (যেমন, ইন ScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)) প্রয়োগ করা অপ্রয়োজনীয় বা খুব ব্যয়বহুল ? তাহলে কি ভাষা উভয় ইন্টারফেস বজায় রাখার কোনও সুবিধা নেই এমনকি ইতিহাস বর্তমান ফলাফলকে জোর করে না?
সর্বোচ্চ

1
@ ম্যাক্স - আচ্ছা আমি এটি বলেছিলাম, এবং আমি এখনও এর সাথে একমত আছি। তবে এটি একটি গৌণ কারণ। তবে তবুও, আমার সন্দেহ হয় যে সামঞ্জস্যতা বজায় রাখার জন্য যদি প্রয়োজনীয়তা না ঘটে থাকে তবে Runnable এটি সংশোধন করা যেত । এর "বয়লারপ্লেট" return null;একটি দুর্বল যুক্তি। (কমপক্ষে, এটি আমার সিদ্ধান্ত ছিল ... অনুমানের প্রসঙ্গে যেখানে আপনি পিছনের সামঞ্জস্যতা উপেক্ষা করতে পারেন))
স্টিফেন সি

81
  • একটি পদ্ধতি Callableবাস্তবায়নের প্রয়োজন call()যখন পদ্ধতি Runnableপ্রয়োগের প্রয়োজন run()
  • Callableএকটি মান ফেরত দিতে পারে তবে একটি Runnableপারে না।
  • একটি Callableচেক করা ব্যতিক্রম ছুঁড়ে ফেলতে Runnableপারে তবে তা পারে না।
  • এ পদ্ধতিতে Callableব্যবহার করা যেতে পারে ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)তবে Runnableতা হতে পারে না।

    public interface Runnable {
        void run();
    }
    
    public interface Callable<V> {
        V call() throws Exception;
    }

17
এক্সিকিউটর সার্ভিস.সবিমিট (চলমান টাস্ক) এছাড়াও বিদ্যমান এবং খুব দরকারী
ইয়ায়ার কুকিলকা

রানওয়েবল এক্সিকিউটর সার্ভিসের সাথে নিম্নলিখিত পদ্ধতিগুলি ব্যবহার করেও ব্যবহার করা যেতে পারে- ১) এক্সিকিউটর সার্ভিস.সেকিউট (চলমান) ২) এক্সিকিউটর সার্ভিস.সুবমিট (চলমান)
আজম খান

2
এছাড়াও এক্সিকিউটার.সবমিট (কলযোগ্য <T> টাস্ক) রয়েছে তবে আপনি রান আনেবল টাস্ক সংগ্রহের সংগ্রহ সহ সমস্তকে ডাকতে বা ডাকতে পারবেন না <? প্রসারিত Callable <টি >> কর্ম
নিকলী

36

আমি এটি অন্য একটি ব্লগে এটি পেয়েছি যা এই পার্থক্যগুলিকে আরও কিছুটা ব্যাখ্যা করতে পারে :

যদিও উভয় ইন্টারফেসগুলি ক্লাস দ্বারা কার্যকর করা হয়েছে যারা মৃত্যুদন্ডের বিভিন্ন থ্রেডে চালিত করতে চায় তবে দুটি ইন্টারফেসের মধ্যে কয়েকটি পার্থক্য রয়েছে যা হ'ল:

  • একটি Callable<V>উদাহরণ টাইপের ফলাফল প্রদান করে V, যেখানে কRunnable উদাহরণটি দেয় না।
  • একটি Callable<V>উদাহরণ চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে, অন্যদিকে Runnableউদাহরণটি পারে না

জাভার ডিজাইনাররা Runnableইন্টারফেসের সক্ষমতা বাড়ানোর প্রয়োজনীয়তা অনুভব করেছিল , তবে তারা ইন্টারফেসের ব্যবহারগুলিকে প্রভাবিত করতে চায়নি Runnableএবং সম্ভবত এটি কারণ ছিল যে তারা Callableইতিমধ্যে পরিবর্তনের চেয়ে জাভা 1.5 তে একটি পৃথক ইন্টারফেস রাখার জন্য গিয়েছিল বিদ্যমান Runnable


27

আসুন আমরা কোথায় চলুন এবং কলযোগ্য ব্যবহার করতে হবে তা দেখুন।

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

রান্নেবল : আপনার যদি ফায়ার থাকে এবং টাস্ক ভুলে যান তবে রান্নেবল ব্যবহার করুন। আপনার কোডটি রান্নেবলের ভিতরে রাখুন এবং যখন রান () পদ্ধতিটি কল করা হয়, আপনি আপনার কাজটি সম্পাদন করতে পারেন। কলিং থ্রেডটি আপনি যখন আপনার কাজটি সম্পাদন করেন তখন সত্যিই যত্ন করে না।

Callable : আপনি যদি কোনও কাজ থেকে কোনও মান পুনরুদ্ধার করার চেষ্টা করছেন, তবে কলযোগ্য ব্যবহার করুন। এখন নিজে থেকে কল করা কাজটি করবে না। আপনার ভবিষ্যতের দরকার হবে যা আপনি আপনার কলযোগ্যকে ঘিরে রাখবেন এবং ভবিষ্যতে আপনার মানগুলি পেতে পারেন get ভবিষ্যতে ফলাফল ফিরে না আসা পর্যন্ত এখানে কলিং থ্রেডটি অবরুদ্ধ করা হবে যা ঘুরেফিরে কলযোগ্য কল () পদ্ধতিটি কার্যকর করার জন্য অপেক্ষা করছে।

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

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


14

Callableইন্টারফেস call()পদ্ধতি ঘোষণা করে এবং আপনাকে জেনেরিক সরবরাহ করতে হবে যেমন অবজেক্ট কল () ফিরতে হবে -

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Runnableঅন্যদিকে ইন্টারফেস হ'ল এমন run()পদ্ধতিটি ডিক্লেয়ার করে যা যখন আপনি রান্নেবলের সাথে একটি থ্রেড তৈরি করেন এবং তার উপর কল স্টার্ট () কল করেন। আপনি সরাসরি রান () কেও কল করতে পারেন তবে এটি কেবল চালানো () পদ্ধতি একই থ্রেড।

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used 
     * to create a thread, starting the thread causes the object's 
     * <code>run</code> method to be called in that separately executing 
     * thread. 
     * <p>
     * The general contract of the method <code>run</code> is that it may 
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

সংক্ষিপ্ত বিবরণে কয়েকটি উল্লেখযোগ্য পার্থক্য হ'ল

  1. একটি Runnableবস্তু ফলাফল ফেরত দেয় না যখন কোনও Callableবস্তু ফলাফল দেয়।
  2. কোনও Runnableবস্তু একটি চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে না যেখানে কোনও Callableবস্তু ব্যতিক্রম ফেলতে পারে।
  3. Runnableইন্টারফেস জাভা 1.0 যেহেতু হয়েছে প্রায় যেহেতু Callableশুধুমাত্র জাভা 1.5 চালু করা হয়।

কয়েকটি সাদৃশ্য অন্তর্ভুক্ত

  1. চলমানযোগ্য বা কলযোগ্য ইন্টারফেস প্রয়োগকারী ক্লাসগুলির উদাহরণগুলি সম্ভবত অন্য থ্রেড দ্বারা সম্পাদিত হয়।
  2. উভয় কলযোগ্য এবং চলমানযোগ্য ইন্টারফেসের ইনস্ট্যান্স্ট জমা দেওয়া () পদ্ধতির মাধ্যমে এক্সিকিউটর সার্ভিস দ্বারা কার্যকর করা যেতে পারে।
  3. উভয়ই ফাংশনাল ইন্টারফেস এবং জাভা 8 এর পরে লাম্বদা এক্সপ্রেশনগুলিতে ব্যবহার করা যেতে পারে।

এক্সিকিউটর সার্ভিস ইন্টারফেসের পদ্ধতিগুলি

<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);

13

ওরাকল ডকুমেন্টেশন থেকে এই ইন্টারফেসগুলির উদ্দেশ্য:

চলমান ইন্টারফেসটি এমন কোনও শ্রেণীর দ্বারা প্রয়োগ করা উচিত যার উদাহরণগুলি ক দ্বারা চালিত করার উদ্দেশ্যে Thread। শ্রেণিকে অবশ্যই কোনও আর্গুমেন্ট না বলা একটি পদ্ধতি নির্ধারণ করতে হবে run

Callable : একটি কার্য যা ফলাফল দেয় এবং একটি ব্যতিক্রম ছুঁড়ে দিতে পারে। প্রয়োগকারীরা কল নামে ডাকা কোনও যুক্তি ছাড়াই একটি একক পদ্ধতি নির্ধারণ করে। Callableইন্টারফেস অনুরূপ Runnableযে উভয় শ্রেণীর যার দৃষ্টান্ত সম্ভাব্য অন্য থ্রেড দ্বারা মৃত্যুদন্ড কার্যকর করা হয় জন্য ডিজাইন করা হয়। এ Runnableতবে কোনও ফল দেয় না এবং চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে না।

অন্যান্য পার্থক্য:

  1. আপনি Runnableএকটি থ্রেড তৈরি করতে পাস করতে পারেন । কিন্তু আপনি পাস করে নতুন থ্রেড তৈরি করতে পারবেন নাCallable প্যারামিটার হিসাবে । আপনি কল করতে পারবেন কেবলমাত্র ExecutorServiceদৃষ্টান্তগুলিতে pass

    উদাহরণ:

    public class HelloRunnable implements Runnable {
    
        public void run() {
            System.out.println("Hello from a thread!");
        }   
    
        public static void main(String args[]) {
            (new Thread(new HelloRunnable())).start();
        }
    
    }
  2. Runnableফায়ার এবং ভুলে যাওয়া কলগুলির জন্য ব্যবহার করুন । ব্যবহারCallableফলাফল যাচাই করতে ।

  3. Callableবিপরীতভাবে সমস্ত পদ্ধতিতে দাখিল করা যেতে পারে Runnable। পদ্ধতি invokeAnyএবংinvokeAll সবচেয়ে বেশি যে দরকারী বাল্ক সঞ্চালনের ফরম কার্য সম্পাদন, কর্ম একটি সংগ্রহ নির্বাহ এবং তারপর অন্তত একটি বা সব অপেক্ষায় সম্পন্ন করতে

  4. তুচ্ছ পার্থক্য: পদ্ধতির নাম প্রয়োগ করা হবে => এর run()জন্য Runnableএবং এর call()জন্য Callable


11

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

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


আমি ভাবছি জাভাতে থ্রেডের ব্যতিক্রম ছড়িয়ে দেওয়ার উদাহরণ কী? মূল থ্রেড কি সেই ব্যতিক্রম ধরতে সক্ষম হবে? যদি না হয়, আমি কলযোগ্য ব্যবহার করতাম না। অ্যালেক্স, আপনার কি এই সম্পর্কে কিছু অন্তর্দৃষ্টি আছে? ধন্যবাদ!
ট্রিলিয়নস

1
অন্য কোনও কোড হিসাবে কাস্টম থ্রেডে চলমান কোড ব্যতিক্রম ছুঁড়ে ফেলতে পারে। এটি অন্য থ্রেডে ধরতে আপনাকে কাস্টম নোটিফিকেশন মেকানিজম (উদাহরণস্বরূপ শ্রোতার উপর নির্ভরশীল) ব্যবহার করে Futureবা সমস্ত অচেনা ব্যতিক্রম ধরা পড়ে এমন হুক ব্যবহার করে বা কিছু চেষ্টা করতে হবে : ডকস.অরাকল.com
অ্যালেক্সার

দুর্দান্ত তথ্য! ধন্যবাদ, অ্যালেক্স! :)
ট্রিলিয়নস

1
আমি এই উত্তরটিকে অগ্রাহ্য করেছি কারণ এটি দৃ (়ভাবে দাবি করে (সঠিকভাবে যদি মুখের মান হিসাবে নেওয়া হয়) কাউকে অবশ্যই কলযোগ্য বস্তুর সাথে থ্রেড পুল মডেলটি ব্যবহার করতে হবে। এ সম্পর্কে আপাতদৃষ্টিতে দুর্ভাগ্যজনক বিষয়টি হ'ল যে কোনওটি ইন্টারফেসটির Threadঅর্থবহ ব্যবহার করতে প্রসারিত করতে পারে না Callableযাতে একক থ্রেডকে কলযোগ্যযোগ্য জিনিসগুলি এবং বিকাশকারীরা চাইতে পারে এমন অন্যান্য জিনিসগুলি কাস্টমাইজ করতে পারে। যদি কেউ এই মন্তব্যটি পড়ে আমার মনে হয় যে আমি ভুল, আমি আরও ভালভাবে জানতে চাই ...

8
+-------------------------------------+--------------------------------------------------------------------------------------------------+
|              Runnable               |                                           Callable<T>                                            |
+-------------------------------------+--------------------------------------------------------------------------------------------------+
| Introduced in Java 1.0 of java.lang | Introduced in Java 1.5 of java.util.concurrent library                                           |
| Runnable cannot be parametrized     | Callable is a parametrized type whose type parameter indicates the return type of its run method |
| Runnable has run() method           | Callable has call() method                                                                       |
| Runnable.run() returns void         | Callable.call() returns a value of Type T                                                        |
| Can not throw Checked Exceptions    | Can throw Checked Exceptions                                                                     |
+-------------------------------------+--------------------------------------------------------------------------------------------------+

জাভার ডিজাইনাররা Runnableইন্টারফেসের সক্ষমতা বাড়ানোর প্রয়োজনীয়তা অনুভব করেছিল , তবে তারা ইন্টারফেসের ব্যবহারগুলিকে প্রভাবিত করতে চায়নি Runnableএবং সম্ভবত এটি কারণ ছিল যে তারা Callableইতিমধ্যে পরিবর্তনের চেয়ে জাভা 1.5 তে একটি পৃথক ইন্টারফেস রাখার জন্য গিয়েছিল বিদ্যমান Runnableইন্টারফেস যা জাভা 1.0 থেকে জাভা একটি অংশ হয়েছে। সূত্র


7

কলযোগ্য এবং চলমানযোগ্য মধ্যে পার্থক্য নিম্নলিখিত:

  1. কলযোগ্য জেডিকে ৫.০ এ প্রবর্তিত তবে রানডেবল জেডিকে ০.০ এ প্রবর্তিত হয়েছে
  2. কলযোগ্য কল () পদ্ধতি আছে কিন্তু রাননেবল চালিত () পদ্ধতি।
  3. কলযোগ্য কল পদ্ধতি রয়েছে যা মান দেয় তবে রান্নেবলের রান পদ্ধতি রয়েছে যা কোনও মান দেয় না।
  4. কল পদ্ধতি চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে তবে রান পদ্ধতিটি চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে না।
  5. টাস্ক কাতারে রাখার জন্য কলযোগ্য ব্যবহার সাবমিট () পদ্ধতি ব্যবহার করুন তবে টাস্ক কাতারে রাখার জন্য চালনযোগ্য ব্যবহার এক্সিকিউট () পদ্ধতি ব্যবহার করুন।

রানটাইম এক্সেপশন নয়, এই চেক করা ব্যতিক্রমটির উপর জোর দেওয়া গুরুত্বপূর্ণ
বার্টকিং

5

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

চলমান এবং কলযোগ্য মধ্যে পার্থক্য হিসাবে হিসাবে

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

পদ্ধতির স্বাক্ষর - চলমান ->

public void run(){}

Callable->

public Object call(){}

২) রান্নেবল রান () পদ্ধতির ক্ষেত্রে যদি কোনও পরীক্ষিত ব্যতিক্রম দেখা দেয় তবে আপনার অবশ্যই চেষ্টা ক্যাচ ব্লক দিয়ে পরিচালনা করতে হবে ক্রি তবে কলযোগ্য কল () পদ্ধতির ক্ষেত্রে আপনি নীচের মতো চেক করা ব্যতিক্রম নিক্ষেপ করতে পারেন

 public Object call() throws Exception {}

3) চলমানযোগ্য লিগ্যাসি জাভা 1.0 সংস্করণ থেকে আসে , কিন্তু callable এসে জাভা 1.5 সঙ্গে সংস্করণ Executer ফ্রেমওয়ার্ক।

আপনার সাথে পরিচিত থাকেন Executers তারপর আপনি উচিত runnable পরিবর্তে Callable ব্যবহার

আশা করি বুঝতে পেরেছো.


2

চলমান (বনাম) কলযোগ্য পয়েন্টে আসে যখন আমরা কাঠামো ব্যবহার করি।

এক্সিকিউটর Executorসার্ভিস একটি সাব-ইন্টারফেস, এটি রান্নেবল এবং কলযোগ্য উভয় কাজই গ্রহণ করে।

প্রথম থেকে মাল্টি-থ্রেডিং 1.0 থেকে ইন্টারফেস ব্যবহার করে অর্জন করা যেতে পারে , তবে এখানে সমস্যাটি থ্রেড টাস্কটি সম্পন্ন করার পরে আমরা থ্রেডস তথ্য সংগ্রহ করতে অক্ষম। যাতে আমরা স্ট্যাটিক ক্ষেত্রগুলি ব্যবহার করতে পারি সেই ডেটা সংগ্রহ করার জন্য।Runnable

উদাহরণ প্রতিটি শিক্ষার্থীর ডেটা সংগ্রহ করতে থ্রেড পৃথক করুন।

static HashMap<String, List> multiTasksData = new HashMap();
public static void main(String[] args) {
    Thread t1 = new Thread( new RunnableImpl(1), "T1" );
    Thread t2 = new Thread( new RunnableImpl(2), "T2" );
    Thread t3 = new Thread( new RunnableImpl(3), "T3" );

    multiTasksData.put("T1", new ArrayList() ); // later get the value and update it.
    multiTasksData.put("T2", new ArrayList() );
    multiTasksData.put("T3", new ArrayList() );
}

এই সমস্যা সমাধানের জন্য তারা 1.5 থেকে প্রবর্তন করেছে যা ফলাফল দেয় এবং একটি ব্যতিক্রম ছুঁড়ে দিতে পারে।Callable<V>

  • একক বিমূর্ত পদ্ধতি : কলযোগ্য এবং চলমান উভয় ইন্টারফেসের একটি একক বিমূর্ত পদ্ধতি রয়েছে যার অর্থ তারা জাভা 8-এ ল্যাম্বডা এক্সপ্রেশনে ব্যবহার করতে পারবেন।

    public interface Runnable {
    public void run();
    }
    
    public interface Callable<Object> {
        public Object call() throws Exception;
    }

এক্সিকিউটর সার্ভিসে মৃত্যুদন্ড কার্যকর করার জন্য কয়েকটি ভিন্ন ভিন্ন উপায় রয়েছে ।

  • execute(Runnable task):void নতুন থ্রেডকে ক্রেট করে তবে মূল থ্রেড বা কলার থ্রেডকে ব্লক করে না কারণ এই পদ্ধতিটি বাতিল হয়ে যায়।
  • submit(Callable<?>):Future<?>, submit(Runnable):Future<?>নতুন থ্রেডকে ক্রেট করে এবং যখন আপনি ভবিষ্যত.জেট () ব্যবহার করেন তখন মূল থ্রেড অবরোধ করে ।

ইন্টারফেস চালানো, এক্সিকিউটর ফ্রেমওয়ার্ক সহ কলযোগ্য ব্যবহারের উদাহরণ।

class CallableTask implements Callable<Integer> {
    private int num = 0;
    public CallableTask(int num) {
        this.num = num;
    }
    @Override
    public Integer call() throws Exception {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " : Started Task...");

        for (int i = 0; i < 5; i++) {
            System.out.println(i + " : " + threadName + " : " + num);
            num = num + i;
            MainThread_Wait_TillWorkerThreadsComplete.sleep(1);
        }
        System.out.println(threadName + " : Completed Task. Final Value : "+ num);

        return num;
    }
}
class RunnableTask implements Runnable {
    private int num = 0;
    public RunnableTask(int num) {
        this.num = num;
    }
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " : Started Task...");

        for (int i = 0; i < 5; i++) {
            System.out.println(i + " : " + threadName + " : " + num);
            num = num + i;
            MainThread_Wait_TillWorkerThreadsComplete.sleep(1);
        }
        System.out.println(threadName + " : Completed Task. Final Value : "+ num);
    }
}
public class MainThread_Wait_TillWorkerThreadsComplete {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.out.println("Main Thread start...");
        Instant start = java.time.Instant.now();

        runnableThreads();
        callableThreads();

        Instant end = java.time.Instant.now();
        Duration between = java.time.Duration.between(start, end);
        System.out.format("Time taken : %02d:%02d.%04d \n", between.toMinutes(), between.getSeconds(), between.toMillis()); 

        System.out.println("Main Thread completed...");
    }
    public static void runnableThreads() throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        Future<?> f1 = executor.submit( new RunnableTask(5) );
        Future<?> f2 = executor.submit( new RunnableTask(2) );
        Future<?> f3 = executor.submit( new RunnableTask(1) );

        // Waits until pool-thread complete, return null upon successful completion.
        System.out.println("F1 : "+ f1.get());
        System.out.println("F2 : "+ f2.get());
        System.out.println("F3 : "+ f3.get());

        executor.shutdown();
    }
    public static void callableThreads() throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        Future<Integer> f1 = executor.submit( new CallableTask(5) );
        Future<Integer> f2 = executor.submit( new CallableTask(2) );
        Future<Integer> f3 = executor.submit( new CallableTask(1) );

        // Waits until pool-thread complete, returns the result.
        System.out.println("F1 : "+ f1.get());
        System.out.println("F2 : "+ f2.get());
        System.out.println("F3 : "+ f3.get());

        executor.shutdown();
    }
}

0

এটি এক ধরণের ইন্টারফেস নামকরণ কনভেনশন যা ক্রিয়ামূলক প্রোগ্রামিংয়ের সাথে মেলে

//Runnable
interface Runnable {
    void run();
}

//Action - throws exception
interface Action {
    void run() throws Exception;
}

//Consumer - consumes a value/values, throws exception
interface Consumer1<T> {
    void accept(T t) throws Exception;
}

//Callable - return result, throws exception
interface Callable<R> {
    R call() throws Exception;
}

//Supplier - returns result, throws exception
interface Supplier<R> {
    R get() throws Exception;
}

//Predicate - consumes a value/values, returns true or false, throws exception
interface Predicate1<T> {
    boolean test(T t) throws Exception;
}

//Function - consumes a value/values, returns result, throws exception
public interface Function1<T, R> {
    R apply(T t) throws Throwable;
}

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