চলমান সমস্যা

আপনি ইতিমধ্যেই রানেবল ইন্টারফেস এবং থ্রেড ক্লাসের সাথে পরিচিত যা এটি প্রয়োগ করে। আসুন মনে করি এই ইন্টারফেসটি কেমন দেখাচ্ছে:


public interface Runnable {
	public abstract void run();
}

মনে রাখবেন যে রান পদ্ধতির রিটার্ন টাইপ void । কিন্তু যদি আমাদের থ্রেডের প্রয়োজন হয় তার কাজের কিছু ফলাফল একটি সংখ্যা, একটি স্ট্রিং বা অন্য কোনো বস্তুর আকারে? তারপর আমরা একটি সমাধান সঙ্গে আসা আবশ্যক. এটার মতো কিছু:


public class Fibonacci implements Runnable {
 
 
 
	private final int index;
 
	private int result;
 
 
 
	public Fibonacci(int index) {
 
    		this.index = index;
 
	}
 
 
 
	@Override
 
	public void run() {
 
    		int first = 0;
 
    		int second = 1;
 
    		if (index == 1) {
 
        			result = first;
 
    		} else if (index == 2) {
 
        			result = second;
 
    		} else {
 
        			for (int i = 0; i < index - 2; i++) {
 
            				int temp = second;
 
            				second += first;
 
            				first = temp;
 
        			}
 
 
 
            			result = second;
 
    		}
 
	}
 
 
 
	public static void printByIndex(int index) throws InterruptedException {
 
    		Fibonacci fibonacci = new Fibonacci(index);
 
    		Thread thread = new Thread(fibonacci);
 
    		thread.start();
 
    		thread.join();
 
    		System.out.println("Fibonacci number " + index + ": " + fibonacci.result);
 
	}
 
}

আসুন নিম্নলিখিত প্রধান পদ্ধতিটি চালাই:


	public static void main(String[] args) throws Exception {
    		Fibonacci.printByIndex(10);
	}

কনসোল প্রদর্শন করবে:

ফিবোনাচি সংখ্যা 10: 34

এই কোডের বেশ কিছু ত্রুটি রয়েছে। উদাহরণস্বরূপ, যোগদান পদ্ধতিতে কলের ফলে , printByIndex পদ্ধতিটি কার্যকর হওয়ার সময় মূল থ্রেডটি ব্লক হয়ে যাবে ।

কলযোগ্য ইন্টারফেস

এখন চলুন ইন্টারফেসটি দেখি যা জাভা আমাদেরকে বাক্সের বাইরে সরবরাহ করে, যা Runnable এর বিকল্প হিসাবে ব্যবহার করা যেতে পারে । এটি কলযোগ্য ইন্টারফেস:


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

আপনি দেখতে পাচ্ছেন, Runnable এর মতো , এটির একটি মাত্র পদ্ধতি রয়েছে। এই পদ্ধতিটি রান পদ্ধতির মতো একই উদ্দেশ্যে কাজ করে — এতে কোড রয়েছে যা সমান্তরাল থ্রেডে কার্যকর করা হবে। পার্থক্যের জন্য, রিটার্ন মান একবার দেখুন। এখন ইন্টারফেস বাস্তবায়ন করার সময় আপনি নির্দিষ্ট যে কোনো ধরনের হতে পারে:


public class CurrentDate implements Callable<Long> {
 
	@Override
 
	public Long call() {
 
    		return new Date().getTime();
 
	}
 
}

আরেকটি উদাহরণ:


Callable<String> task = () -> {
 
	Thread.sleep(100);
 
	return "Done";
 
};

এখানে অন্য কিছু দরকারী — কল পদ্ধতি একটি ব্যতিক্রম নিক্ষেপ করতে পারে । এর মানে হল যে, রান পদ্ধতির বিপরীতে, কল পদ্ধতিতে আমাদের পদ্ধতির ভিতরে থাকা চেক করা ব্যতিক্রমগুলি পরিচালনা করতে হবে না:


public class Sleep implements Runnable {

	@Override

	public void run() {

    	    try {

        	        Thread.sleep(1000);

    	    } catch (InterruptedException ignored) {

    	    }

	}

}

public class Sleep implements Callable {

	@Override

	public Object call() throws InterruptedException {

    	    Thread.sleep(1000);

    	    return null;

	}

}

ভবিষ্যতের ইন্টারফেস

কলেবলের সাথে ঘনিষ্ঠভাবে কাজ করে এমন আরেকটি ইন্টারফেস হল Futureভবিষ্যত অ্যাসিঙ্ক্রোনাস (সমান্তরাল) গণনার ফলাফলকে প্রতিনিধিত্ব করে ( কল পদ্ধতি দ্বারা ফেরত দেওয়া মান)। এটি আপনাকে গণনা করা হয়েছে কিনা তা পরীক্ষা করতে, গণনা শেষ হওয়ার জন্য অপেক্ষা করতে, গণনার ফলাফল পেতে এবং আরও অনেক কিছু করতে দেয়।

ভবিষ্যতের ইন্টারফেসের পদ্ধতি

  • বুলিয়ান isDone() — এই কাজটি (গণনা) করা হলে এই পদ্ধতিটি সত্য হয়। যে কার্যগুলি সাধারণত শেষ হয়, একটি ব্যতিক্রম সহ শেষ হয় বা বাতিল করা হয় সেগুলি সম্পন্ন বলে বিবেচিত হয়৷

  • V get() — যদি প্রয়োজন হয়, এই পদ্ধতিটি থ্রেডটিকে ব্লক করে যেটি এটিকে বলে, এবং সেগুলি সম্পন্ন হলে গণনার ফলাফল প্রদান করে।

  • V get(লং টাইমআউট, টাইমইউনিট ইউনিট) — আগের পদ্ধতির মতো, এই পদ্ধতিটি থ্রেডটিকে ব্লক করে যা এটিকে বলে, ফলাফলের জন্য অপেক্ষা করে, কিন্তু শুধুমাত্র পদ্ধতির পরামিতি দ্বারা নির্দিষ্ট সময়ের জন্য।

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

  • বুলিয়ান isCancelled() — এই পদ্ধতিটি সঠিকভাবে ফিরে আসে যদি টাস্কটি স্বাভাবিকভাবে শেষ হওয়ার আগে বাতিল করা হয়। বাতিল পদ্ধতিটি পূর্বে কল করা হলে এবং সত্য ফেরত দিলে পদ্ধতিটি সর্বদা সত্য হবে ।

কলযোগ্য এবং ভবিষ্যত ব্যবহার করে কোডের উদাহরণ


import java.util.HashMap;
 
import java.util.Map;
 
import java.util.concurrent.*;
 
 
 
public class Fibonacci implements Callable<Integer> {
 
 
 
	private final int index;
 
 
 
	public Fibonacci(int index) {
 
    		this.index = index;
 
	}
 
 
 
	@Override
 
	public Integer call() {
 
    		int first = 0;
 
    		int second = 1;
 
    		if (index == 1) {
 
        			return first;
 
    		} else if (index == 2) {
 
        			return second;
 
    		} else {
 
        		for (int i = 0; i < index - 2; i++) {
 
            			int temp = second;
 
            			second += first;
 
            			first = temp;
 
        		}
 
 
 
        			return second;
 
    		}
 
	}
 
 
 
	public static Future<Integer> calculateAsync(int index) throws Exception {
 
    		Fibonacci fibonacci = new Fibonacci(index);
 
 
 
    		// The future object will represent the result of running the fibonacci task.
 
    		FutureTask<Integer> future = new FutureTask<>(fibonacci);
 
 
 
    		// Because the FutureTask class implements both the Future interface and the Runnable interface,
 
	 	// you can pass instances of it to the Thread constructor
 
    		Thread thread = new Thread(future);
 
    		thread.start();
 
 
 
    		return future;
 
	}
 
}

আসুন নিম্নলিখিত প্রধান পদ্ধতিটি চালাই:


	public static void main(String[] args) throws Exception {
    		Map<Integer, Future<Integer>> tasks = new HashMap<>();
    		for (int i = 10; i < 20; i++) {
        			tasks.put(i, Fibonacci.calculateAsync(i));
    		}
 
    		for (Map.Entry<Integer, Future<Integer>> entry : tasks.entrySet()) {
        			Future<Integer> task = entry.getValue();
        			int index = entry.getKey();
        			int result;
        			// Check whether the task is done
        			if (task.isDone()) {
            				// Get the result of the calculations
            				result = task.get();
        			} else {
            				try {
                				// Wait another 100 milliseconds for the result of the calculations
                				result = task.get(100, TimeUnit.MILLISECONDS);
            				} catch (TimeoutException e) {
                				// Interrupt the task
                				task.cancel(true);
                				System.out.println("Fibonacci number " + index + " could not be calculated in the allotted time.");
                				return;
            				}
        			}
        			System.out.println("Fibonacci number " + index + ": " + result);
    		}
	}

কনসোল প্রদর্শন করবে:

ফিবোনাচি নম্বর 16: 610
ফিবোনাচি নম্বর 17: 987
ফিবোনাচি নম্বর 18: 1597
ফিবোনাচি নম্বর 19: 2584
ফিবোনাচি নম্বর 10: 34
ফিবোনাচি নম্বর 11: 55 ফিবোনাচি
নম্বর 12
: 89
ফিবোনাচি নম্বর: 431
ফিবোনাচি নম্বর 341 15: 377