উত্তর:
ব্যাখ্যা এখানে দেখুন ।
কলযোগ্য ইন্টারফেসটি রান্নেবলের অনুরূপ, এতে উভয়ই এমন ক্লাসগুলির জন্য ডিজাইন করা হয়েছে যার উদাহরণগুলি সম্ভবত অন্য থ্রেড দ্বারা সম্পাদিত হয়। একটি রান্নেবল, তবে ফল দেয় না এবং চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে না।
অ্যাপ্লিকেশন
Runnable
এবং এর মধ্যে পার্থক্য কিCallable
। পার্থক্যটি কি কেবল রিটার্ন প্যারামিটারে উপস্থিত রয়েছেCallable
?
মূলত, হ্যাঁ এই প্রশ্নের উত্তর দেখুন । এবং জাভাদোকCallable
।
উভয় থাকার প্রয়োজন যদি
Callable
সমস্ত কিছু করতেRunnable
পারে?
কারন Runnable
ইন্টারফেসটি যা করতে পারে তা করতে পারে নাCallable
!
Runnable
জাভা ০.০ থেকে প্রায় Callable
ছিল , তবে কেবল জাভা 1.5 তে চালু হয়েছিল ... এমন ব্যবহার-কেসগুলি Runnable
সমর্থন করে না যা সমর্থন করে না। তত্ত্ব অনুসারে, জাভা দলটি Runnable.run()
পদ্ধতির স্বাক্ষর পরিবর্তন করতে পারত , তবে এটি প্রাক-1.5 কোডের সাথে বাইনারি কম্প্যাটিবিলিটিটি ভেঙে ফেলত, পুরানো জাভা কোডটি নতুন জেভিএমগুলিতে স্থানান্তরিত করার সময় পুনরায় কোডিং প্রয়োজন। এটি একটি বড় নম্বর-না N জাভা পিছনের দিকে সামঞ্জস্যপূর্ণ হতে চেষ্টা করে ... এবং এটি ব্যবসায় কম্পিউটিংয়ের জন্য জাভার অন্যতম বৃহত্তম বিক্রয় পয়েন্ট।
এবং, স্পষ্টতই, এমন ব্যবহারের কেস রয়েছে যেখানে কোনও কাজের জন্য ফলাফল ফেরত দেওয়ার বা চেক করা ব্যতিক্রম নিক্ষেপের প্রয়োজন হয় না । এই ব্যবহারের ক্ষেত্রে, পদ্ধতিটি থেকে ডামি ( ) মান Runnable
ব্যবহার করা Callable<Void>
এবং ফেরানোর চেয়ে ব্যবহার আরও সংক্ষিপ্ত ।null
call()
Runnable
পশ্চাদগম্য সামঞ্জস্যতার কারণে উপস্থিত থাকার (মূলত) পরামর্শ দিচ্ছেন । কিন্তু এমন পরিস্থিতি নেই যেখানে Callable
ইন্টারফেস (যেমন, ইন ScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)
) প্রয়োগ করা অপ্রয়োজনীয় বা খুব ব্যয়বহুল ? তাহলে কি ভাষা উভয় ইন্টারফেস বজায় রাখার কোনও সুবিধা নেই এমনকি ইতিহাস বর্তমান ফলাফলকে জোর করে না?
Runnable
এটি সংশোধন করা যেত । এর "বয়লারপ্লেট" return null;
একটি দুর্বল যুক্তি। (কমপক্ষে, এটি আমার সিদ্ধান্ত ছিল ... অনুমানের প্রসঙ্গে যেখানে আপনি পিছনের সামঞ্জস্যতা উপেক্ষা করতে পারেন))
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;
}
আমি এটি অন্য একটি ব্লগে এটি পেয়েছি যা এই পার্থক্যগুলিকে আরও কিছুটা ব্যাখ্যা করতে পারে :
যদিও উভয় ইন্টারফেসগুলি ক্লাস দ্বারা কার্যকর করা হয়েছে যারা মৃত্যুদন্ডের বিভিন্ন থ্রেডে চালিত করতে চায় তবে দুটি ইন্টারফেসের মধ্যে কয়েকটি পার্থক্য রয়েছে যা হ'ল:
Callable<V>
উদাহরণ টাইপের ফলাফল প্রদান করে V
, যেখানে কRunnable
উদাহরণটি দেয় না।Callable<V>
উদাহরণ চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে, অন্যদিকে Runnable
উদাহরণটি পারে নাজাভার ডিজাইনাররা Runnable
ইন্টারফেসের সক্ষমতা বাড়ানোর প্রয়োজনীয়তা অনুভব করেছিল , তবে তারা ইন্টারফেসের ব্যবহারগুলিকে প্রভাবিত করতে চায়নি Runnable
এবং সম্ভবত এটি কারণ ছিল যে তারা Callable
ইতিমধ্যে পরিবর্তনের চেয়ে জাভা 1.5 তে একটি পৃথক ইন্টারফেস রাখার জন্য গিয়েছিল বিদ্যমান Runnable
।
আসুন আমরা কোথায় চলুন এবং কলযোগ্য ব্যবহার করতে হবে তা দেখুন।
চলমান এবং কলযোগ্য উভয়ই কলিং থ্রেডের চেয়ে পৃথক থ্রেডে চালান। কিন্তু কলযোগ্য একটি মান ফিরিয়ে দিতে পারে এবং রাননেবল পারবেন না। সুতরাং কোথায় এটি সত্যিই প্রযোজ্য।
রান্নেবল : আপনার যদি ফায়ার থাকে এবং টাস্ক ভুলে যান তবে রান্নেবল ব্যবহার করুন। আপনার কোডটি রান্নেবলের ভিতরে রাখুন এবং যখন রান () পদ্ধতিটি কল করা হয়, আপনি আপনার কাজটি সম্পাদন করতে পারেন। কলিং থ্রেডটি আপনি যখন আপনার কাজটি সম্পাদন করেন তখন সত্যিই যত্ন করে না।
Callable : আপনি যদি কোনও কাজ থেকে কোনও মান পুনরুদ্ধার করার চেষ্টা করছেন, তবে কলযোগ্য ব্যবহার করুন। এখন নিজে থেকে কল করা কাজটি করবে না। আপনার ভবিষ্যতের দরকার হবে যা আপনি আপনার কলযোগ্যকে ঘিরে রাখবেন এবং ভবিষ্যতে আপনার মানগুলি পেতে পারেন get ভবিষ্যতে ফলাফল ফিরে না আসা পর্যন্ত এখানে কলিং থ্রেডটি অবরুদ্ধ করা হবে যা ঘুরেফিরে কলযোগ্য কল () পদ্ধতিটি কার্যকর করার জন্য অপেক্ষা করছে।
সুতরাং কোনও লক্ষ্য শ্রেণীর কাছে এমন ইন্টারফেসের কথা চিন্তা করুন যেখানে আপনার চালনযোগ্য এবং কলযোগ্য দুটি মোড়ানো পদ্ধতি সংজ্ঞায়িত রয়েছে। কলিং ক্লাস এলোমেলোভাবে আপনার ইন্টারফেসের পদ্ধতিগুলিতে কল করবে যা জেনে নেই কোনটি রানযোগ্য এবং কোনটি কলযোগ্য। চলমান পদ্ধতিগুলি কলযোগ্য পদ্ধতি না বলা অবধি তাত্পর্যপূর্ণভাবে কার্যকর করা হবে। আপনি কলিং ক্লাসের থ্রেডটি ব্লক হবে যেহেতু আপনি আপনার লক্ষ্য শ্রেণীর থেকে মানগুলি পুনরুদ্ধার করছেন।
দ্রষ্টব্য: আপনার টার্গেট শ্রেণীর ভিতরে আপনি কল করতে পারেন কল করতে পারবেন এবং একক থ্রেড এক্সিকিউটারের উপর রান্নেবল, এই ব্যবস্থাটি সিরিয়াল প্রেরণের সারির মতো করে making সুতরাং কলার যতক্ষণ না আপনার রান্নেবল মোড়ানো পদ্ধতিগুলিকে কল করে ততক্ষণ কলিং থ্রেডটি ব্লক না করে সত্যিই দ্রুত কার্যকর করা হবে। ভবিষ্যতের পদ্ধতিতে মোড়ানো একটি কলযোগ্য কল করার সাথে সাথে এটি অন্যান্য সারিবদ্ধ আইটেমগুলি সম্পাদন না করা অবধি ব্লক করতে হবে। তবেই পদ্ধতিটি মান সহ ফিরে আসবে। এটি একটি সিঙ্ক্রোনাইজেশন প্রক্রিয়া।
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();
}
সংক্ষিপ্ত বিবরণে কয়েকটি উল্লেখযোগ্য পার্থক্য হ'ল
Runnable
বস্তু ফলাফল ফেরত দেয় না যখন কোনও Callable
বস্তু ফলাফল দেয়।Runnable
বস্তু একটি চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে না যেখানে কোনও Callable
বস্তু ব্যতিক্রম ফেলতে পারে।Runnable
ইন্টারফেস জাভা 1.0 যেহেতু হয়েছে প্রায় যেহেতু Callable
শুধুমাত্র জাভা 1.5 চালু করা হয়।কয়েকটি সাদৃশ্য অন্তর্ভুক্ত
এক্সিকিউটর সার্ভিস ইন্টারফেসের পদ্ধতিগুলি
<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
ওরাকল ডকুমেন্টেশন থেকে এই ইন্টারফেসগুলির উদ্দেশ্য:
চলমান ইন্টারফেসটি এমন কোনও শ্রেণীর দ্বারা প্রয়োগ করা উচিত যার উদাহরণগুলি ক দ্বারা চালিত করার উদ্দেশ্যে Thread
। শ্রেণিকে অবশ্যই কোনও আর্গুমেন্ট না বলা একটি পদ্ধতি নির্ধারণ করতে হবে run
।
Callable : একটি কার্য যা ফলাফল দেয় এবং একটি ব্যতিক্রম ছুঁড়ে দিতে পারে। প্রয়োগকারীরা কল নামে ডাকা কোনও যুক্তি ছাড়াই একটি একক পদ্ধতি নির্ধারণ করে। Callable
ইন্টারফেস অনুরূপ Runnable
যে উভয় শ্রেণীর যার দৃষ্টান্ত সম্ভাব্য অন্য থ্রেড দ্বারা মৃত্যুদন্ড কার্যকর করা হয় জন্য ডিজাইন করা হয়। এ Runnable
তবে কোনও ফল দেয় না এবং চেক করা ব্যতিক্রম ছুঁড়ে ফেলতে পারে না।
অন্যান্য পার্থক্য:
আপনি 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();
}
}
Runnable
ফায়ার এবং ভুলে যাওয়া কলগুলির জন্য ব্যবহার করুন । ব্যবহারCallable
ফলাফল যাচাই করতে ।
Callable
বিপরীতভাবে সমস্ত পদ্ধতিতে দাখিল করা যেতে পারে Runnable
। পদ্ধতি invokeAny
এবংinvokeAll
সবচেয়ে বেশি যে দরকারী বাল্ক সঞ্চালনের ফরম কার্য সম্পাদন, কর্ম একটি সংগ্রহ নির্বাহ এবং তারপর অন্তত একটি বা সব অপেক্ষায় সম্পন্ন করতে
তুচ্ছ পার্থক্য: পদ্ধতির নাম প্রয়োগ করা হবে => এর run()
জন্য Runnable
এবং এর call()
জন্য Callable
।
এটি ইতিমধ্যে এখানে উল্লিখিত ছিল যে কলযোগ্য অপেক্ষাকৃত নতুন ইন্টারফেস এবং এটি সম্মতি প্যাকেজের অংশ হিসাবে চালু হয়েছিল। উভয় কলযোগ্য এবং চলমানযোগ্য এক্সিকিউটরগুলির সাথে ব্যবহার করা যেতে পারে। ক্লাস থ্রেড (যা রান্নেবল নিজেই প্রয়োগ করে) কেবল রান্নেবলকে সমর্থন করে।
আপনি এখনও এক্সিকিউটরদের সাথে রান্নেবল ব্যবহার করতে পারেন। কলযোগ্য এর সুবিধা যা আপনি এটি নির্বাহকের কাছে প্রেরণ করতে এবং তাত্ক্ষণিকভাবে ফিরে পেতে পারেন ফিউচার ফলাফল যা কার্যকর করা শেষ হলে আপডেট হবে। এটি রান্নেবলের সাথে বাস্তবায়িত হতে পারে তবে এই ক্ষেত্রে আপনাকে ফলাফলগুলি নিজেই পরিচালনা করতে হবে। উদাহরণস্বরূপ আপনি ফলাফলের সারি তৈরি করতে পারেন যা সমস্ত ফলাফলকে ধারণ করবে। অন্যান্য থ্রেড এই কাতারে অপেক্ষা করতে পারে এবং আগত ফলাফলগুলি ডিল করতে পারে।
Future
বা সমস্ত অচেনা ব্যতিক্রম ধরা পড়ে এমন হুক ব্যবহার করে বা কিছু চেষ্টা করতে হবে : ডকস.অরাকল.com
Thread
অর্থবহ ব্যবহার করতে প্রসারিত করতে পারে না Callable
যাতে একক থ্রেডকে কলযোগ্যযোগ্য জিনিসগুলি এবং বিকাশকারীরা চাইতে পারে এমন অন্যান্য জিনিসগুলি কাস্টমাইজ করতে পারে। যদি কেউ এই মন্তব্যটি পড়ে আমার মনে হয় যে আমি ভুল, আমি আরও ভালভাবে জানতে চাই ...
+-------------------------------------+--------------------------------------------------------------------------------------------------+
| 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 থেকে জাভা একটি অংশ হয়েছে। সূত্র
কলযোগ্য এবং চলমানযোগ্য মধ্যে পার্থক্য নিম্নলিখিত:
কলযোগ্য এবং চলমান উভয়ই একে অপরের সাথে সমান এবং থ্রেড প্রয়োগ করতে ব্যবহার করতে পারে। রান্নেবল বাস্তবায়নের ক্ষেত্রে আপনাকে অবশ্যই রান () পদ্ধতি প্রয়োগ করতে হবে তবে কল করার ক্ষেত্রে অবশ্যই কল () পদ্ধতি প্রয়োগ করতে হবে , উভয় পদ্ধতি একই পদ্ধতিতে কাজ করে তবে কলযোগ্য কল () পদ্ধতিতে আরও নমনীয়তা রয়েছে them তাদের মধ্যে কিছু পার্থক্য রয়েছে।
চলমান এবং কলযোগ্য মধ্যে পার্থক্য হিসাবে হিসাবে
১) রানযোগ্য অযোগ্য রিটার্নের রান () পদ্ধতিটির অর্থ যদি আপনার থ্রেড এমন কিছু ফেরত চান যা আপনি আরও ব্যবহার করতে পারেন তবে আপনার কাছে রান্নেবল রান () পদ্ধতিতে কোনও বিকল্প নেই । 'কলয়েবল' এর একটি সমাধান রয়েছে , আপনি যদি কোনও বস্তুর আকারে কোনও কিছু ফিরিয়ে দিতে চান তবে আপনার রান্নেবলের পরিবর্তে কলযোগ্য ব্যবহার করা উচিত । কলযোগ্য ইন্টারফেসের পদ্ধতি 'কল ()' রয়েছে যা প্রত্যাশাকে রিটার্ন দেয় ।
পদ্ধতির স্বাক্ষর - চলমান ->
public void run(){}
Callable->
public Object call(){}
২) রান্নেবল রান () পদ্ধতির ক্ষেত্রে যদি কোনও পরীক্ষিত ব্যতিক্রম দেখা দেয় তবে আপনার অবশ্যই চেষ্টা ক্যাচ ব্লক দিয়ে পরিচালনা করতে হবে ক্রি তবে কলযোগ্য কল () পদ্ধতির ক্ষেত্রে আপনি নীচের মতো চেক করা ব্যতিক্রম নিক্ষেপ করতে পারেন
public Object call() throws Exception {}
3) চলমানযোগ্য লিগ্যাসি জাভা 1.0 সংস্করণ থেকে আসে , কিন্তু callable এসে জাভা 1.5 সঙ্গে সংস্করণ Executer ফ্রেমওয়ার্ক।
আপনার সাথে পরিচিত থাকেন Executers তারপর আপনি উচিত runnable পরিবর্তে Callable ব্যবহার ।
আশা করি বুঝতে পেরেছো.
চলমান (বনাম) কলযোগ্য পয়েন্টে আসে যখন আমরা কাঠামো ব্যবহার করি।
এক্সিকিউটর 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();
}
}
এটি এক ধরণের ইন্টারফেস নামকরণ কনভেনশন যা ক্রিয়ামূলক প্রোগ্রামিংয়ের সাথে মেলে
//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;
}
...