Deadlock Example: Deadlock কিভাবে কাজ করে এবং এটি কিভাবে প্রতিরোধ করা যায়

Multithreading Examples - জাভা উদাহরন (Java  Examples) - Java Technologies

383

ডেডলক হচ্ছে একটি পরিস্থিতি যেখানে দুটি বা ততোধিক থ্রেড একে অপরকে ব্লক করে রেখে এমন একটি অবস্থা সৃষ্টি করে, যেখানে তারা সবাই একে অপরের জন্য অপেক্ষা করছে। এতে, কোনো থ্রেডই সম্পূর্ণ হতে পারে না, এবং সিস্টেম "হ্যাং" হয়ে পড়ে।

এটি সাধারাণত ঘটে যখন একাধিক থ্রেড একে অপরের মধ্যে একই রিসোর্সের জন্য অপেক্ষা করছে এবং তারা একে অপরকে ওই রিসোর্স মুক্ত করার জন্য বাধা সৃষ্টি করে।

ডেডলক উদাহরণ:

নিচে একটি উদাহরণ দেওয়া হয়েছে যেখানে দুটি থ্রেড একে অপরের জন্য রিসোর্স ব্লক করছে এবং ডেডলক তৈরি হচ্ছে।

public class DeadlockExample {
    // প্রথম রিসোর্স
    private static final Object resource1 = new Object();
    // দ্বিতীয় রিসোর্স
    private static final Object resource2 = new Object();

    public static void main(String[] args) {
        // প্রথম থ্রেড
        Thread thread1 = new Thread(() -> {
            synchronized (resource1) {
                System.out.println("Thread 1: Locked resource 1");

                // দ্বিতীয় রিসোর্সের জন্য অপেক্ষা
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                
                synchronized (resource2) {
                    System.out.println("Thread 1: Locked resource 2");
                }
            }
        });

        // দ্বিতীয় থ্রেড
        Thread thread2 = new Thread(() -> {
            synchronized (resource2) {
                System.out.println("Thread 2: Locked resource 2");

                // প্রথম রিসোর্সের জন্য অপেক্ষা
                try { Thread.sleep(100); } catch (InterruptedException e) {}

                synchronized (resource1) {
                    System.out.println("Thread 2: Locked resource 1");
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}

কোড ব্যাখ্যা:

এই উদাহরণে, thread1 প্রথমে resource1 লক করে এবং পরে resource2 লক করতে চায়। অপরদিকে, thread2 প্রথমে resource2 লক করে এবং পরে resource1 লক করতে চায়। এখন, thread1 resource2 লক করার জন্য অপেক্ষা করছে, এবং thread2 resource1 লক করার জন্য অপেক্ষা করছে। তাই দুটি থ্রেড একে অপরকে ব্লক করে, এবং ডেডলক সৃষ্টি হয়।

ডেডলক প্রতিরোধ:

ডেডলক প্রতিরোধের জন্য বেশ কয়েকটি পদ্ধতি রয়েছে। নিচে কিছু পদ্ধতির বর্ণনা দেওয়া হল:

১. ডেডলক ফ্রি লকিং অর্ডার:

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

উদাহরণ:

public class DeadlockPrevention {
    private static final Object resource1 = new Object();
    private static final Object resource2 = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (resource1) {
                System.out.println("Thread 1: Locked resource 1");

                synchronized (resource2) {
                    System.out.println("Thread 1: Locked resource 2");
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            synchronized (resource1) {
                System.out.println("Thread 2: Locked resource 1");

                synchronized (resource2) {
                    System.out.println("Thread 2: Locked resource 2");
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}

এখানে, আমরা নিশ্চিত করেছি যে thread1 এবং thread2 উভয়েই প্রথম resource1 লক করবে এবং পরে resource2 লক করবে, ফলে ডেডলক এড়ানো যাবে।

২. টাইমআউট ব্যবহার:

ডেডলক এড়ানোর জন্য কিছু থ্রেড একটি নির্দিষ্ট সময় পর লকিং অ্যাকশনটি ত্যাগ করতে পারে। এটি ডেডলক পরিস্থিতি এড়াতে সাহায্য করে।

public class DeadlockWithTimeout {
    private static final Object resource1 = new Object();
    private static final Object resource2 = new Object();

    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            try {
                if (tryLock(resource1, 1000) && tryLock(resource2, 1000)) {
                    System.out.println("Thread 1: Locked both resources");
                } else {
                    System.out.println("Thread 1: Could not acquire both resources");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                if (tryLock(resource2, 1000) && tryLock(resource1, 1000)) {
                    System.out.println("Thread 2: Locked both resources");
                } else {
                    System.out.println("Thread 2: Could not acquire both resources");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
    }

    private static boolean tryLock(Object resource, long timeout) throws InterruptedException {
        synchronized (resource) {
            return true;
        }
    }
}

এখানে, tryLock মেথড ব্যবহার করে, থ্রেড একটি নির্দিষ্ট সময় পর রিসোর্স অ্যাক্সেস চেষ্টা করে এবং সফল না হলে একটি ত্রুটি বার্তা প্রিন্ট করে।

৩. ডেডলক ডিটেকশন:

ডেডলক সনাক্ত করতে একটি মনিটরিং সিস্টেম তৈরি করা যেতে পারে যা থ্রেডদের সিস্টেমে থাকা অবস্থার উপর নজর রাখে এবং ডেডলক ঘটলে সিস্টেমকে রিসেট করে।


ডেডলক একটি সাধারণ সমস্যা হতে পারে, তবে উপযুক্ত পরিকল্পনা ও ডিজাইন কৌশল ব্যবহার করে এটি প্রতিরোধ করা সম্ভব। সঠিক লকিং অর্ডার অনুসরণ, টাইমআউট ব্যবহার, এবং ডেডলক সনাক্তকরণের মাধ্যমে সিস্টেমের কর্মক্ষমতা বজায় রাখা সম্ভব।

Content added By
Promotion

Are you sure to start over?

Loading...