এই থ্রেড কোড যুক্ত মানে কি?


156

এই কোডটিতে, দুজনে যোগ দেয় এবং বিরতি বলতে কী বোঝায়? শেষ না হওয়া পর্যন্ত থামার t1.join()কারণ ?t2t1

Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread t2 = new Thread(new EventThread("e2"));
t2.start();
while (true) {
   try {
      t1.join();
      t2.join();
      break;
   } catch (InterruptedException e) {
      e.printStackTrace();
   }
}


3
যেহেতু এটি থ্রেড সমাপ্তির জন্য অবরুদ্ধ হবে এবং অপেক্ষা করবে, তাই আপনি কেন লুপটি ব্যবহার করলেন?
মেহেদি

@ মাহদীএলমাসৌদি আমি মনে করি, থ্রেডটি বাধাগ্রস্ত হয়ে থাকলেও অপেক্ষা করতে থাকি? সম্ভবত এটি করার দুর্দান্ত উপায় নয়
forresthopkinsa

উত্তরটি যদি সহায়ক হয় তবে তা গ্রহণ করতে ভুলবেন না।
ধূসর

উল্লিখিত হিসাবে, আপনার পদ্ধতিটি while(true)কল করার প্রয়োজন নেই join
চাকলাদার আসফাক আরেফি

উত্তর:


311

এই থ্রেড কোড যুক্ত মানে কি?

Thread.join()পদ্ধতি জাভাদোক থেকে উদ্ধৃত :

join() এই থ্রেডটি মারা যাওয়ার জন্য অপেক্ষা করে।

এমন একটি থ্রেড রয়েছে যা আপনার উদাহরণ কোডটি চালাচ্ছে যা সম্ভবত মূল থ্রেড

  1. মূল থ্রেড তৈরি করে t1এবং t2থ্রেডগুলি শুরু করে । দুটি থ্রেড সমান্তরালে চলতে শুরু করে।
  2. মূল থ্রেডটি থ্রেডটি শেষ হওয়ার t1.join()জন্য অপেক্ষা করতে কল করে t1
  3. t1থ্রেড সমাপ্ত হবে এবং t1.join()মূল থ্রেড পদ্ধতি আয়। নোট করুন যে কল t1করার আগেই join()কলটি হওয়ার আগেই শেষ হয়ে যেতে পারে যে ক্ষেত্রে join()কলটি তত্ক্ষণাত্ ফিরে আসবে।
  4. মূল থ্রেডটি থ্রেডটি শেষ হওয়ার t2.join()জন্য অপেক্ষা করতে কল করে t2
  5. দ্য t2থ্রেড সম্পন্ন হয়ে (অথবা এটা সম্পন্ন থাকতে পারে আগে t1থ্রেড করেনি) এবং t2.join()মূল থ্রেড পদ্ধতি আয়।

এটি বুঝতে গুরুত্বপূর্ণ যে থ্রেডগুলি t1এবং t2থ্রেডগুলি সমান্তরালভাবে চলছে তবে মূল থ্রেড যা সেগুলি শুরু করেছিল তা চালিয়ে যাওয়ার আগে তাদের সমাপ্ত হওয়ার জন্য অপেক্ষা করা প্রয়োজন। এটি একটি সাধারণ প্যাটার্ন। এছাড়াও, t1এবং / অথবা মূল থ্রেড কল করার আগেt2 শেষ করতে পারতjoin() তাদের করার । যদি তাই হয় তবে join()অপেক্ষা করবেন না তবে অবিলম্বে ফিরে আসবেন।

t1.join() টি 1 টি বন্ধ না হওয়া পর্যন্ত টি 2 বন্ধ করার কারণ?

না। মূল থ্রেডটি যা কল করছে t1.join()তা চলমান বন্ধ করবে এবং t1থ্রেডটি শেষ হওয়ার অপেক্ষা করবে । t2থ্রেড সমান্তরাল চলমান এবং দ্বারা প্রভাবিত হয় নাt1 বা t1.join()এ সব কল।

চেষ্টা / ধরার ক্ষেত্রে, join()নিক্ষেপ করা InterruptedExceptionমানে যে মূল থ্রেডটি কল join()করছে তা অন্য থ্রেডের দ্বারা নিজেই বাধা পেতে পারে।

while (true) {

একটি whileলুপে যোগদান করা একটি অদ্ভুত বিন্যাস। সাধারণত আপনি প্রথম যোগদান এবং দ্বিতীয় InterruptedExceptionক্ষেত্রে প্রতিটি ক্ষেত্রে যথাযথভাবে পরিচালনা করতে হবে । এগুলি একটি লুপে রাখার দরকার নেই।


24
+1 এটি একটি খুব অদ্ভুত প্যাটার্ন এবং সম্ভবত মুছে ফেলা যেতে পারে।
m0skit0

3
যদি টি 1 প্রথমে সমাপ্ত হয়, তবে শেষ করতে টি 2 করুন। এটি একটি অনুক্রমিক প্রক্রিয়া বলে মনে হচ্ছে। একটি থ্রেড প্রথমে শেষ হয়, তারপরে অন্যটি। একাধিক থ্রেডিং এর বিন্দু কি?
ব্যবহারকারী 697911

9
কারণ t1এবং t2সমান্তরাল চালানো যেতে পারে। এটি ঠিক যে mainএটি চালিয়ে যাওয়ার আগে তাদের উভয়ের প্রয়োজন শেষ করা উচিত। এটি একটি সাধারণ প্যাটার্ন @ ব্যবহারকারী 697911।
গ্রে

3
whileলুপ আছে কারণ (আমি অনুমান) এটি পুনরায় চেষ্টা করতে চায় join()যদি কেউ বিঘ্নিত কল? আমি অবশ্যই @ user797911 এভাবে লিখব না।
গ্রে

5
লুপটি সেখানে উভয়ই নিশ্চিত করে t1এবং t2শেষ করে। অর্থাৎ। যদি এটি t1ছুড়ে ফেলে তবে InterruptedExceptionএটি লুপ হয়ে ফিরে অপেক্ষা করবে t2। একটি বিকল্প হ'ল তাদের উভয় চেষ্টা-ক্যাপ উভয় থ্রেডের জন্য অপেক্ষা করা, যাতে লুপটি এড়ানো যায়। এছাড়াও, এর উপর নির্ভর করে EventThread, এটি এটি করার জন্য এটি বুদ্ধিমান হতে পারে, কারণ আমরা 2 টি থ্রেড চালাচ্ছি, একটি নয়।
মাইকেল বিসবার্গ

68

এটি জাভা সাক্ষাত্কারের একটি প্রিয় প্রশ্ন।

Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread e2 = new Thread(new EventThread("e2"));
t2.start();

while (true) {
    try {
        t1.join(); // 1
        t2.join(); // 2  These lines (1,2) are in in public static void main
        break;
    }
}

t1.join()এর অর্থ, টি 1 " আমি প্রথমে শেষ করতে চাই" এর মতো কিছু বলে । একই অবস্থা t2। নির্বিশেষে যারা শুরু t1বা t2থ্রেড (এই ক্ষেত্রে mainপদ্ধতি), প্রধান পর্যন্ত অপেক্ষা করবে t1এবং t2তাদের কাজের শেষ।

যাইহোক, একটি গুরুত্বপূর্ণ পয়েন্ট নিচে খেয়াল করা, t1এবং t2নিজেদের সমান্তরাল নির্বিশেষে চালানো কল ক্রম যোগ দিতে পারেন উপর t1এবং t2। এটি main/daemonথ্রেড যে অপেক্ষা করতে হবে


3
ভালো উদাহরণ. "সমান্তরালভাবে চলতে পারে" সম্পর্কে: তাহলে কী? এটি গুরুত্বপূর্ণ যে মূল থ্রেড টিআরটির জন্য FIRST এবং T2 এর জন্য THEN অপেক্ষা করবে। আসলে টি 1 বা টি 2 কী করছে তা মুখ্য নয় (মূল থ্রেডের দৃষ্টিকোণ থেকে)
অ্যালেক্স

1
আপনি "মূল / ডেমন" থ্রেডটি উল্লেখ করেছেন। মূল আমি বুঝতে পারি তবে ডেমনের সাথে এর কোনও সম্পর্ক নেই। মূল থ্রেডটি নন-ডেমন।
ধূসর

1
t1.join(); t2.join();উভয় থ্রেড শেষ না হওয়া অবধি চালিত থ্রেডগুলিকে যোগ দেওয়ার অনুমতি দেয় না। অন্য কোথাও খুব অস্বাভাবিক কোডের অভাবে, ক্রমের সাথে যোগ দেওয়ার ক্রমটি কোনও ব্যাপার নয়।
ডেভিড শোয়ার্জ

সুতরাং t2.join () কেবল তখনই বলা হবে যখন টি 1 শেষ হবে?
লিও ড্রয়েডকোডার

অন্য কথায়, আমরা যদি টি 1 এবং টি 2 থ্রেডের ক্রিয়াকলাপটি "সিরিয়ালাইজ" করতে চাই, আমাদের মূল থ্রেড টি 1 (এবং পরে টি 2) শুরু হওয়ার পরে t1.start () এর ঠিক পরে t1.join () স্থাপন করা দরকার এবং অবশ্যই এটি থেকে অপসারণ করুন ধরার চেষ্টা কর. স্পষ্টতই, এটি করার ফলে ফলাফলটি সমান্তরালতার ক্ষতি হবে।
dobrivoje

47

join()মানে থ্রেডটি সম্পূর্ণ হওয়ার অপেক্ষায়। এটি একটি ব্লকার পদ্ধতি। আপনার মূল থ্রেড (যেটি এটি করে join()) কাজ শেষ t1.join()না হওয়া অবধি লাইনে অপেক্ষা t1করবে এবং তারপরে একই কাজ করবে t2.join()


29

একটি ছবি হাজার শব্দের সমান.

    Main thread-->----->--->-->--block##########continue--->---->
                 \                 |               |
sub thread start()\                | join()        |
                   \               |               |
                    ---sub thread----->--->--->--finish    

দরকারী আশা করি, আরও বিশদ জন্য এখানে ক্লিক করুন


3
পরিষ্কার এবং সুনির্দিষ্ট
dobrivoje

10

যখন থ্রেড টিএ কল করে টিবি.জাইন () তার কারণগুলি কেবল টিবি মারা যাওয়ার জন্য বা টিএ নিজেই বাধা হওয়ার জন্য অপেক্ষা করে না তবে টিবি থ্রেডে টিবি.জাইনের () পরে শেষ বিবৃতি এবং পরবর্তী বিবৃতিতে সম্পর্কের আগে ঘটে।

কোনও থ্রেডের সমস্ত ক্রিয়াকলাপ ঘটে যায় - অন্য কোনও থ্রেড সফলভাবে সেই থ্রেডের একটি যোগদান () থেকে ফিরে আসার আগে।

এর অর্থ প্রোগ্রাম

class App {
    // shared, not synchronized variable = bad practice
    static int sharedVar = 0;
    public static void main(String[] args) throws Exception {
        Thread threadB = new Thread(() -> {sharedVar = 1;});
        threadB.start();
        threadB.join();

        while (true) 
            System.out.print(sharedVar);
    }
}

সর্বদা মুদ্রণ

>> 1111111111111111111111111 ...

কিন্তু প্রোগ্রাম

class App {
    // shared, not synchronized variable = bad practice
    static int sharedVar = 0;
    public static void main(String[] args) throws Exception {
        Thread threadB = new Thread(() -> {sharedVar = 1;});
        threadB.start();
        // threadB.join();  COMMENT JOIN

        while (true)
            System.out.print(sharedVar);
    }
}

না শুধুমাত্র মুদ্রণ করতে পারেন

>> 0000000000 ... 000000111111111111111111111111 ...

কিন্তু

>> 00000000000000000000000000000000000000000000 ... 

সর্বদা কেবল '0'।

যেহেতু জাভা মেমোরি মডেলকে হেডপেন-পূর্বের সম্পর্ক ছাড়াই থ্রেডবি থেকে মূল থ্রেডে 'শেয়ারডবার'-এর নতুন মান' ট্রান্সফারিং 'প্রয়োজন হয় না (থ্রেড শুরু, থ্রেড জয়েন,' সিঙ্কনাইজড 'কীওয়ার্ডের ব্যবহার, অ্যাটমিকএক্সএক্সএক্স ভেরিয়েবলের ব্যবহার ইত্যাদি)।


5

সোজা কথায়: সম্পূর্ণ
t1.join()হওয়ার পরে রিটার্ন এটি থ্রেড করার জন্য কিছুই করে না , এটি শেষ হওয়ার অপেক্ষা ব্যতীত। স্বাভাবিকভাবে, কোড নিম্নলিখিতগুলি কেবলমাত্র রিটার্নের পরে কার্যকর করা হবে ।t1
t1
t1.join()t1.join()


1
t1.join () +1
mohsen.nour

3

যোগদানগুলিতে ওরাকল ডকুমেন্টেশন পৃষ্ঠা থেকে

joinপদ্ধতি একটি থ্রেড অন্য শেষ হওয়ার জন্য অপেক্ষা করতে পারবেন।

যদি টি 1 এমন কোনও Threadবস্তু হয় যার থ্রেড বর্তমানে চালানো হচ্ছে,

t1.join() : causes the current thread to pause execution until t1's thread terminates.

যদি টি 2 এমন কোনও Threadবস্তু হয় যার থ্রেড বর্তমানে চালানো হচ্ছে,

t2.join(); causes the current thread to pause execution until t2's thread terminates.

joinএপিআই হ'ল নিম্ন স্তরের এপিআই, যা জাভা এর পূর্ববর্তী সংস্করণগুলিতে চালু হয়েছিল। সম্মতিযুক্ত ফ্রন্টে সময়ের সাথে সাথে (বিশেষত জেডিকে 1.5 রিলিজ সহ) প্রচুর জিনিস পরিবর্তন করা হয়েছে।

আপনি java.util.concurrent API এর মাধ্যমে এটি অর্জন করতে পারেন। এর কয়েকটি উদাহরণ

  1. ইনভোকএল সব ব্যবহার করেExecutorService
  2. ব্যবহার কাউন্টডাউনল্যাচ
  3. ব্যবহার ForkJoinPool বা newWorkStealingPool এরExecutors (জাভা 8 থেকে)

সম্পর্কিত এসই সংক্রান্ত প্রশ্নগুলি দেখুন:

সমস্ত থ্রেড জাভাতে তাদের কাজ শেষ না হওয়া পর্যন্ত অপেক্ষা করুন


1

আমার জন্য, যোগদান () আচরণ সর্বদা বিভ্রান্তিকর কারণ আমি মনে করার চেষ্টা করছিলাম কে কার জন্য অপেক্ষা করবে। এটি সেভাবে মনে রাখার চেষ্টা করবেন না।

নীচে, এটি খাঁটি অপেক্ষা () এবং অবহিত () প্রক্রিয়া।

আমরা সবাই জানি যে, আমরা যখন কোনও বস্তুর (টি 1) অপেক্ষা () কল করি তখন কলিং অবজেক্ট (মূল) ওয়েটিং রুমে পাঠানো হয় (অবরুদ্ধ অবস্থা)।

এখানে, মূল থ্রেডটি জয়েন () কে কল করছে যা কভারগুলির নিচে অপেক্ষা ()। এটি সূচিত না হওয়া পর্যন্ত মূল থ্রেড অপেক্ষা করবে। এটি শেষ হয়ে গেলে টি 1 দ্বারা বিজ্ঞপ্তি দেওয়া হয় (থ্রেড সমাপ্তি)।

বিজ্ঞপ্তিটি পাওয়ার পরে, প্রধান অপেক্ষা কক্ষ থেকে বেরিয়ে আসে এবং এটি কার্যকর হয়।


0

আশা করি এটা সাহায্য করবে!

package join;

public class ThreadJoinApp {

    Thread th = new Thread("Thread 1") {
        public void run() {
            System.out.println("Current thread execution - " + Thread.currentThread().getName());
            for (int i = 0; i < 10; i++) {
                System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
            }
        }
    };

    Thread th2 = new Thread("Thread 2") {
        public void run() {
            System.out.println("Current thread execution - " + Thread.currentThread().getName());

            //Thread 2 waits until the thread 1 successfully completes.
            try {
            th.join();
            } catch( InterruptedException ex) {
                System.out.println("Exception has been caught");
            }

            for (int i = 0; i < 10; i++) {
                System.out.println("Current thread execution - " + Thread.currentThread().getName() + " at index - " + i);
            }
        }
    };

    public static void main(String[] args) {
        ThreadJoinApp threadJoinApp = new ThreadJoinApp();
        threadJoinApp.th.start();
        threadJoinApp.th2.start();
    }

    //Happy coding -- Parthasarathy S
}

-3

ধরা যাক আমাদের মূল থ্রেডটি থ্রেড টি 1 এবং টি 2 শুরু করে। এখন, যখন t1.join () বলা হয় তখন থ্রেড টি 1 মারা যাওয়ার পরে মূল থ্রেড নিজেকে স্থগিত করে এবং তারপরে আবার শুরু হয়। একইভাবে, যখন t2.join () সম্পাদন করে, থ্রেড টি 2 মারা যায় এবং তারপরে পুনরায় সূচনা না করা পর্যন্ত মূল থ্রেড নিজেকে আবার স্থগিত করে।

সুতরাং, এটি এইভাবে কাজ করে।

এছাড়াও, যদিও এখানে লুপটি সত্যই প্রয়োজন ছিল না।

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