কিভাবে অন্য থ্রেড সমাপ্ত হয়েছে জানতে হবে?


125

আমার নামের একটি পদ্ধতিযুক্ত একটি অবজেক্ট রয়েছে StartDownload()যা তিনটি থ্রেড শুরু করে।

প্রতিটি থ্রেড সম্পাদন শেষ হলে আমি কীভাবে বিজ্ঞপ্তি পেতে পারি?

থ্রেডের একটি (বা সমস্ত) সমাপ্ত হয়েছে বা এখনও কার্যকর হচ্ছে কিনা তা জানার কোনও উপায় আছে?


উত্তর:


227

আপনি এটি করতে পারেন এমন অনেকগুলি উপায় রয়েছে:

  1. প্রতিটি থ্রেড সম্পূর্ণ হওয়ার জন্য বাধা ফ্যাশনে অপেক্ষা করতে আপনার মূল থ্রেডে থ্রেড.জয়াইন () ব্যবহার করুন , বা
  2. একটি পোলিং ফ্যাশনে থ্রেড.আইসএলাইভ () পরীক্ষা করুন - সাধারণত নিরুৎসাহিত - প্রতিটি থ্রেডটি শেষ না হওয়া পর্যন্ত অপেক্ষা করতে, বা
  3. অপ্রচলিত প্রশ্নে প্রতিটি থ্রেডের জন্য, আপনার অবজেক্টে কোনও পদ্ধতি কল করতে setUncaughtExceptionHandler কল করুন এবং প্রতিটি থ্রেডটি সম্পূর্ণ হওয়ার পরে একটি অবিচ্ছিন্ন ব্যতিক্রম ছুঁড়ে ফেলার জন্য প্রোগ্রাম করুন, বা
  4. Java.util.concurrent , বা থেকে লক বা সিঙ্ক্রোনাইজার বা প্রক্রিয়া ব্যবহার করুন
  5. আরও গোঁড়া, আপনার মূল থ্রেডে শ্রোতা তৈরি করুন এবং তারপরে আপনার প্রতিটি থ্রেড প্রোগ্রাম শ্রোতাদের জানান যে তারা সম্পন্ন হয়েছে।

আইডিয়া # 5 কীভাবে বাস্তবায়ন করবেন? ভাল, একটি উপায় হ'ল প্রথমে একটি ইন্টারফেস তৈরি করা:

public interface ThreadCompleteListener {
    void notifyOfThreadComplete(final Thread thread);
}

তারপরে নিম্নলিখিত ক্লাসটি তৈরি করুন:

public abstract class NotifyingThread extends Thread {
  private final Set<ThreadCompleteListener> listeners
                   = new CopyOnWriteArraySet<ThreadCompleteListener>();
  public final void addListener(final ThreadCompleteListener listener) {
    listeners.add(listener);
  }
  public final void removeListener(final ThreadCompleteListener listener) {
    listeners.remove(listener);
  }
  private final void notifyListeners() {
    for (ThreadCompleteListener listener : listeners) {
      listener.notifyOfThreadComplete(this);
    }
  }
  @Override
  public final void run() {
    try {
      doRun();
    } finally {
      notifyListeners();
    }
  }
  public abstract void doRun();
}

এবং তারপরে আপনার প্রতিটি থ্রেড প্রসারিত হবে NotifyingThreadএবং প্রয়োগের পরিবর্তেrun() হবে doRun()। সুতরাং এগুলি যখন সম্পূর্ণ হবে, তারা স্বয়ংক্রিয়ভাবে বিজ্ঞপ্তির জন্য অপেক্ষা করা কাউকে অবহিত করবে।

অবশেষে, আপনার মূল ক্লাসে - সমস্ত থ্রেড শুরু করা এক (বা কমপক্ষে অবজেক্টটি বিজ্ঞপ্তির অপেক্ষায় রয়েছে) - সেই ক্লাসটি সংশোধন করুন implement ThreadCompleteListenerএবং প্রতিটি থ্রেড তৈরি করার সাথে সাথেই শ্রোতার তালিকায় নিজেকে যুক্ত করুন:

NotifyingThread thread1 = new OneOfYourThreads();
thread1.addListener(this); // add ourselves as a listener
thread1.start();           // Start the Thread

তারপরে, প্রতিটি থ্রেডটি প্রস্থান করার সাথে সাথে আপনার notifyOfThreadComplete করার সাথে সাথে পদ্ধতিটি স্রেফ সম্পন্ন (বা ক্র্যাশ হওয়া) থ্রেডের উদাহরণ সহকারে ডাকা হবে।

নোট যে ভাল হবে implements Runnableবরং extends Threadজন্য NotifyingThreadযেমন থ্রেড ব্যাপ্ত সাধারণত নতুন কোডে নিরুৎসাহিত করা হয়। তবে আমি আপনার প্রশ্নের কোডিং করছি। আপনি যদি NotifyingThreadক্লাসটি বাস্তবায়নের জন্য পরিবর্তন করেন Runnableতবে আপনাকে আপনার কোডের কিছু পরিবর্তন করতে হবে যা থ্রেডস পরিচালনা করে, যা করা বেশ সোজা।


ওহে!! আমি শেষ ধারণা পছন্দ। আমি কি শ্রোতা তা বাস্তবায়ন করব? ধন্যবাদ
রিকার্ডো ফেলগিরিস

4
তবে এই পদ্ধতির সাহায্যে notifiyListeners কে রান () এর ভিতরে ডাকা হয় তাই এটি থ্রেডকে ইনসাইড বলা হবে এবং আরও কলগুলি সেখানেও করা হবে, এটি কি এভাবে নয়?
জর্ডি পুইগডেলভোল

1
@ এডি জর্ডি জিজ্ঞাসা করছিলেন, যদি notifyপদ্ধতিটি কল করা সম্ভব হয় তবে runপদ্ধতিটি ইনসিন্ড না করা হলেও এর পরে করা উচিত।
টমাসজ ডিজিসিলেলিউস্কি

1
প্রশ্নটি আসলে: আপনি এখন দ্বিতীয় থ্রেডের অফ কীভাবে পাবেন । আমি জানি যে এটি শেষ হয়েছে, তবে কীভাবে আমি এখন মূল থ্রেডটি অ্যাক্সেস করব ?
প্যাট্রিক

1
এই থ্রেডটি কি নিরাপদ? দেখা যাচ্ছে যে শ্রোতা নিজেই তৈরি করেছেন এমন থ্রেডের পরিবর্তে notifyListeners (এবং এইভাবে notifyOfThreadComplete) কে নোটিফিংথ্রেডের মধ্যে কল করা হবে।
অ্যারন

13

সাইক্লিকবারিয়ার ব্যবহার করে সমাধান

public class Downloader {
  private CyclicBarrier barrier;
  private final static int NUMBER_OF_DOWNLOADING_THREADS;

  private DownloadingThread extends Thread {
    private final String url;
    public DownloadingThread(String url) {
      super();
      this.url = url;
    }
    @Override
    public void run() {
      barrier.await(); // label1
      download(url);
      barrier.await(); // label2
    }
  }
  public void startDownload() {
    // plus one for the main thread of execution
    barrier = new CyclicBarrier(NUMBER_OF_DOWNLOADING_THREADS + 1); // label0
    for (int i = 0; i < NUMBER_OF_DOWNLOADING_THREADS; i++) {
      new DownloadingThread("http://www.flickr.com/someUser/pic" + i + ".jpg").start();
    }
    barrier.await(); // label3
    displayMessage("Please wait...");
    barrier.await(); // label4
    displayMessage("Finished");
  }
}

লেবেল ০ - এক্সিকিউটিভের মূল থ্রেডের জন্য নির্বাহী থ্রেডের সংখ্যার সমান পার্টির সংখ্যা সমেত চক্রীয় বাধা তৈরি করা হয় (যেখানে স্টার্টডাউনলোড () কার্যকর করা হচ্ছে)

লেবেল 1 - এন-তম ডাউনলোডিংথ্রেড ওয়েটিং রুমে প্রবেশ করে

লেবেল 3 - NUMBER_OF_DOWNLOADING_THREADS ওয়েটিং রুমে প্রবেশ করেছে। মৃত্যুদন্ড কার্যকর করার মূল থ্রেড একই সাথে কমবেশি তাদের ডাউনলোডের কাজগুলি শুরু করতে মুক্তি দেয়

লেবেল 4 - মৃত্যুদন্ডের মূল থ্রেড ওয়েটিং রুমে প্রবেশ করে। এটি কোডের 'কৌশলযুক্ত' অংশটি বোঝার জন্য। কোন থ্রেড দ্বিতীয়বারের জন্য ওয়েটিং রুমে প্রবেশ করবে তা বিবেচ্য নয়। এটি গুরুত্বপূর্ণ যে সর্বশেষ থ্রেডটি ঘরে প্রবেশ করে তা নিশ্চিত করে যে অন্যান্য ডাউনলোডের থ্রেডগুলি তাদের ডাউনলোড করার কাজ শেষ করেছে।

লেবেল 2 - এন-তম ডাউনলোডিংথ্রেড এটি ডাউনলোড করার কাজ শেষ করে ওয়েটিং রুমে প্রবেশ করেছে। যদি এটি শেষ হয় তবে ইতিমধ্যে NUMBER_OF_DOWNLOADING_THREADS মৃত্যুদন্ডের মূল থ্রেড সহ এটি প্রবেশ করেছে, অন্য সমস্ত থ্রেডগুলি ডাউনলোড শেষ হলেই মূল থ্রেডটি কার্যকর হবে।


9

আপনার যে সমাধানটি ব্যবহার করে তা সত্যিই পছন্দ করা উচিত java.util.concurrent। এই বিষয়টিতে জোশ ব্লচ এবং / বা ব্রায়ান গোয়েজ সন্ধান করুন এবং পড়ুন।

আপনি যদি ব্যবহার না করে থাকেন java.util.concurrent.*এবং সরাসরি থ্রেডগুলি ব্যবহার করার জন্য দায় নিচ্ছেন, তবে আপনার join()কোনও থ্রেডটি কখন করা হয়েছে তা সম্ভবত জানা উচিত। এখানে একটি দুর্দান্ত সাধারণ কলব্যাক প্রক্রিয়া। Runnableকলব্যাক পেতে প্রথমে ইন্টারফেসটি প্রসারিত করুন :

public interface CallbackRunnable extends Runnable {
    public void callback();
}

তারপরে এমন একটি নির্বাহক করুন যা আপনার চলমান কার্যকর করবে এবং এটি হয়ে গেলে আপনাকে আবার কল করবে।

public class CallbackExecutor implements Executor {

    @Override
    public void execute(final Runnable r) {
        final Thread runner = new Thread(r);
        runner.start();
        if ( r instanceof CallbackRunnable ) {
            // create a thread to perform the callback
            Thread callerbacker = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        // block until the running thread is done
                        runner.join();
                        ((CallbackRunnable)r).callback();
                    }
                    catch ( InterruptedException e ) {
                        // someone doesn't want us running. ok, maybe we give up.
                    }
                }
            });
            callerbacker.start();
        }
    }

}

আপনার CallbackRunnableইন্টারফেসে অন্য ধরণের সুস্পষ্ট জিনিসটি হ'ল কোনও ব্যতিক্রম হ্যান্ডেল করার একটি উপায়, তাই সম্ভবত public void uncaughtException(Throwable e);সেখানে এবং আপনার নির্বাহকের মধ্যে একটি লাইন রাখুন, আপনাকে একটি ইন্টারফেস পদ্ধতিতে প্রেরণের জন্য একটি থ্রেড ইনস্টল করুন U

তবে যা আসলেই গন্ধ পেতে শুরু করে সেগুলি করা java.util.concurrent.Callablejava.util.concurrentআপনার প্রকল্পটির অনুমতি দিলে আপনার ব্যবহারের দিকে সত্যই নজর দেওয়া উচিত ।


আপনি কেবল কলিং বনাম এই কলব্যাক প্রক্রিয়া থেকে আপনি কী অর্জন করেছেন তা সম্পর্কে আমি কিছুটা অস্পষ্ট runner.join()এবং তারপরে আপনি যা যা কোড চান তার পরে আপনি জানেন যে থ্রেডটি শেষ হয়েছে has এটি কি কেবল রান কোডের সম্পত্তি হিসাবে সেই কোডটি সংজ্ঞায়িত করতে পেরেছেন, যাতে আপনার বিভিন্ন রানকেটে আলাদা আলাদা জিনিস থাকতে পারে?
স্টিফেন

2
হ্যাঁ, runner.join()অপেক্ষা করার সর্বাধিক প্রত্যক্ষ উপায়। আমি ধরে নিচ্ছিলাম যে ওপি তাদের মূল কলিং থ্রেডটি ব্লক করতে চায় না, যেহেতু তারা প্রতিটি ডাউনলোডের জন্য "অবহিত" হতে বলেছে, যা কোনও ক্রমে সম্পূর্ণ হতে পারে। এটি তাত্পর্যপূর্ণভাবে বিজ্ঞপ্তি পাওয়ার এক উপায় অফার করেছে।
broc.seib

4

আপনি কি তাদের শেষ হওয়ার জন্য অপেক্ষা করতে চান? যদি তা হয় তবে যোগদানের পদ্ধতিটি ব্যবহার করুন।

আপনি যদি এটি যাচাই করতে চান তবে সেখানে রয়েছে আইভেল সম্পত্তি।


3
নোট করুন যে থ্রেডটি এখনও চালানো শুরু না করে থাকলেইএলাইভ মিথ্যা প্রত্যাবর্তন করে (এমনকি যদি আপনার নিজস্ব থ্রেড ইতিমধ্যে এটি শুরু করে বলেছে)।
টম হাটিন -

@ টমহাউটিন-ট্যাকলাইন আপনি কি সে সম্পর্কে যথেষ্ট নিশ্চিত? এটি জাভা ডকুমেন্টেশনের বিরোধিতা করবে ("থ্রেডটি যদি এটি শুরু করা হয় এবং এখনও মারা যায় না তবে এটি বেঁচে থাকবে" - ডকসস.ওরাকল . com / জাভ্যাস / 6 / ডকস / এপি / জাভা / আংআং / )। এটি এখানে উত্তরগুলির সাথেও বিরোধিতা করবে ( স্ট্যাকওভারফ্লো / প্রশ্ন / 17293304/… )
স্টিফেন

@ স্টেফেন দীর্ঘদিন ধরে আমি এটি লিখেছিলাম, তবে এটি সত্য বলে মনে হচ্ছে। আমি ভাবছি এটি নয় বছর আগে আমার স্মৃতিতে সতেজ হওয়া অন্যান্য লোকেদের সমস্যা সৃষ্টি করেছিল। ঠিক যা পর্যবেক্ষণযোগ্য তা বাস্তবায়নের উপর নির্ভর করবে। আপনি একটি বল Threadকরতে start, যা থ্রেড না, কিন্তু কল রিটার্ন অবিলম্বে। isAliveএকটি সরল পতাকা পরীক্ষা হওয়া উচিত, তবে যখন আমি এটি গুগল করতাম তখন পদ্ধতিটি ছিল native
টম হাটিন - 21

4

আপনি getState () দিয়ে থ্রেড উদাহরণটি জিজ্ঞাসাবাদ করতে পারেন যা থ্রেডের উদাহরণ দেয়। নীচের মানগুলির সাথে স্টেট গণনা:

*  NEW
  A thread that has not yet started is in this state.
* RUNNABLE
  A thread executing in the Java virtual machine is in this state.
* BLOCKED
  A thread that is blocked waiting for a monitor lock is in this state.
* WAITING
  A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
* TIMED_WAITING
  A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
* TERMINATED
  A thread that has exited is in this state.

তবে আমি মনে করি যে একটি মাস্টার থ্রেড রাখা আরও ভাল ডিজাইন হবে যা 3 বাচ্চার সমাপ্ত হওয়ার জন্য অপেক্ষা করে, তারপরে অন্য 3 টি শেষ হয়ে গেলে মাস্টার মৃত্যুদন্ড কার্যকর করবেন।


3 বাচ্চাদের প্রস্থান করার জন্য অপেক্ষা করা ব্যবহারের দৃষ্টিতে উপযুক্ত নয়। যদি এটি ডাউনলোড ম্যানেজার হয় তবে তারা 15 ডাউনলোডগুলি শুরু করতে এবং স্ট্যাটাস বার থেকে স্ট্যাটাসটি সরাতে বা ডাউনলোড শেষ হলে ব্যবহারকারীকে সতর্ক করতে পারে, এই ক্ষেত্রে কলব্যাক আরও ভাল কাজ করতে পারে work
ডিজিটালজেল

3

এক্সিকিউটর সার্ভিস থ্রেড পুল Executorsতৈরি করতে আপনি এই বস্তুটিও ব্যবহার করতে পারেন । তারপরে invokeAllআপনার প্রতিটি থ্রেড চালাতে এবং ফিউচারগুলি পুনরুদ্ধার করতে পদ্ধতিটি ব্যবহার করুন । এটি কার্যকর হবে যতক্ষণ না সকলের কাজ শেষ হয়। আপনার অন্য বিকল্পটি awaitTerminationহ'ল পুলটি ব্যবহার করে প্রত্যেককে মৃত্যুদণ্ড কার্যকর করা এবং তারপরে পুলটি কার্যকর হওয়া শেষ না হওয়া অবধি ব্লকে কল করা। shutdownআপনার কাজগুলি যুক্ত করার পরে কেবল () কল করতে ভুলবেন না ।


2

মাল্টি-থ্রেডিং ফ্রন্টে গত 6 বছরে অনেক কিছুই পরিবর্তন করা হয়েছে।

join()এপিআই ব্যবহার এবং লক করার পরিবর্তে আপনি ব্যবহার করতে পারেন

1. এক্সিকিউটর সার্ভিস invokeAll() এপিআই

প্রদত্ত টাস্কগুলি কার্যকর করে ফিউচারগুলির একটি তালিকা ফিরিয়ে তাদের স্ট্যাটাস এবং ফলাফলগুলি সম্পূর্ণ হয়ে গেলে।

2. কাউন্টডাউনল্যাচ

একটি সিঙ্ক্রোনাইজেশন সহায়তা যা অন্য থ্রেডে পরিচালিত ক্রিয়াকলাপের সেট সম্পূর্ণ না হওয়া পর্যন্ত এক বা একাধিক থ্রেড অপেক্ষা করতে দেয়।

CountDownLatchএকটি প্রদত্ত গণনা দিয়ে আরম্ভ করা হয়। পদ্ধতির অনুরোধের কারণে বর্তমান গণনা শূন্যের না হওয়া পর্যন্ত অপেক্ষা করা পদ্ধতিগুলি অবরুদ্ধ হয়ে যায় countDown(), যার পরে সমস্ত অপেক্ষার থ্রেড প্রকাশিত হয় এবং তত্ক্ষণাত প্রত্যাবর্তনের প্রত্যাবর্তনের অনুরোধ জানানো হয়। এটি একটি শট ঘটনা - গণনাটি পুনরায় সেট করা যায় না। আপনার যদি এমন কোনও সংস্করণ প্রয়োজন হয় যা গণনাটিকে পুনরায় সেট করে, সাইক্লিকবারিয়ার ব্যবহার বিবেচনা করুন।

3. ForkJoinPool বা newWorkStealingPool()মধ্যে নির্বাহক অন্যান্য উপায়

4. Futureজমা দেওয়া থেকে সমস্ত কার্যের মাধ্যমে সনাক্ত করুন ExecutorServiceএবং অবরুদ্ধ কল সাথে স্ট্যাটাসটি পরীক্ষা get()করুনFuture বস্তু

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

এমন থ্রেডের জন্য কীভাবে অপেক্ষা করতে হবে যা এটি নিজের থ্রেডকে ছড়িয়ে দিয়েছে?

নির্বাহকগণ: কাজগুলি পুনরাবৃত্তভাবে তৈরি করা হয় যদি সমস্ত কাজ সমাপ্ত না হয় ততক্ষণ সমকালীনভাবে কীভাবে অপেক্ষা করবেন?


2

আমি থ্রেড ক্লাসের জাভাদোকের দিকে তাকানোর পরামর্শ দেব ।

থ্রেড ম্যানিপুলেশনের জন্য আপনার একাধিক প্রক্রিয়া রয়েছে।

  • আপনার মূল থ্রেডটি join()তিনটি থ্রেড ক্রমিকভাবে করতে পারে এবং ততক্ষণে তিনটি সম্পন্ন না হওয়া পর্যন্ত অগ্রসর হবে না।

  • বিরতিতে প্রসারিত থ্রেডগুলির থ্রেডের অবস্থাটি পোল করুন।

  • একটি পৃথক মধ্যে উত্পন্ন হওয়া থ্রেডের সব রাখুন ThreadGroupও ভোটের activeCount()উপর ThreadGroupএবং এটি 0 পেতে জন্য অপেক্ষা করুন।

  • আন্তঃ থ্রেড যোগাযোগের জন্য একটি কাস্টম কলব্যাক বা শ্রোতার ধরণের ইন্টারফেস সেটআপ করুন।

আমি নিশ্চিত যে আমি এখনও নিখোঁজ প্রচুর অন্যান্য উপায় রয়েছে।


1

এখানে একটি সমাধান যা সহজ, সংক্ষিপ্ত, সহজে বোঝা যায় এবং আমার পক্ষে পুরোপুরি কাজ করে। যখন অন্য থ্রেডটি শেষ হবে তখন আমার স্ক্রিনে আঁকতে হবে; তবে পারেনি কারণ মূল থ্রেডটির স্ক্রিনের নিয়ন্ত্রণ রয়েছে। তাই:

(1) আমি বিশ্বব্যাপী পরিবর্তনশীল তৈরি করেছি: boolean end1 = false; থ্রেডটি শেষ হওয়ার সাথে সাথে এটি সত্যে সেট করে। এটি মূল পোস্টে "পোস্টডিলিয়েড" লুপটি নিয়ে যায়, যেখানে এটির প্রতিক্রিয়া জানানো হয়।

(২) আমার থ্রেডে রয়েছে:

void myThread() {
    end1 = false;
    new CountDownTimer(((60000, 1000) { // milliseconds for onFinish, onTick
        public void onFinish()
        {
            // do stuff here once at end of time.
            end1 = true; // signal that the thread has ended.
        }
        public void onTick(long millisUntilFinished)
        {
          // do stuff here repeatedly.
        }
    }.start();

}

(3) সৌভাগ্যক্রমে, "পোস্টডিলিয়েড" মূল থ্রেডে চালিত হয়, যাতে প্রতি সেকেন্ডে একবারে অন্য থ্রেডটি পরীক্ষা করা হয়। অন্য থ্রেডটি শেষ হয়ে গেলে, আমরা পরবর্তী যা কিছু করতে চাই তা এটি শুরু করতে পারে।

Handler h1 = new Handler();

private void checkThread() {
   h1.postDelayed(new Runnable() {
      public void run() {
         if (end1)
            // resond to the second thread ending here.
         else
            h1.postDelayed(this, 1000);
      }
   }, 1000);
}

(৪) পরিশেষে, কল করে আপনার কোডের কোথাও পুরোটা চালানো শুরু করুন:

void startThread()
{
   myThread();
   checkThread();
}

1

আমি অনুমান করি সবচেয়ে সহজ উপায়টি ThreadPoolExecutorক্লাস ব্যবহার করা ।

  1. এটির একটি সারি রয়েছে এবং সমান্তরালে কত থ্রেড কাজ করা উচিত তা আপনি সেট করতে পারেন।
  2. এটিতে দুর্দান্ত কলব্যাক পদ্ধতি রয়েছে:

হুক পদ্ধতি

এই শ্রেণিটি সুরক্ষিত ওভারিডেবল beforeExecute(java.lang.Thread, java.lang.Runnable)এবং afterExecute(java.lang.Runnable, java.lang.Throwable)পদ্ধতিগুলি সরবরাহ করে যা প্রতিটি কার্য সম্পাদনের আগে এবং পরে ডাকা হয়। এগুলি কার্যকর করার পরিবেশকে কাজে লাগাতে ব্যবহৃত হতে পারে; উদাহরণস্বরূপ, থ্রেডলোকালগুলিকে পুনরায়ায়ন করা, পরিসংখ্যান সংগ্রহ করা বা লগ এন্ট্রি যুক্ত করা। অতিরিক্তভাবে, terminated()এক্সিকিউটারের সম্পূর্ণরূপে সমাপ্ত হওয়ার পরে কোনও বিশেষ প্রক্রিয়াজাতকরণ করার জন্য পদ্ধতিটি ওভাররাইড করা যেতে পারে।

যা আমাদের ঠিক প্রয়োজন। afterExecute()প্রতিটি থ্রেড হয়ে যাওয়ার পরে আমরা কলব্যাকগুলি পেতে ওভাররাইড করব এবং ওভাররাইড করবterminated() সমস্ত থ্রেডগুলি শেষ হয়ে গেলে তা জানতে করব।

সুতরাং এখানে আপনার করা উচিত

  1. একটি নির্বাহক তৈরি করুন:

    private ThreadPoolExecutor executor;
    private int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();    
    
    
    
    private void initExecutor() {
    
    executor = new ThreadPoolExecutor(
            NUMBER_OF_CORES * 2,  //core pool size
            NUMBER_OF_CORES * 2, //max pool size
            60L, //keep aive time
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>()
    ) {
    
        @Override
        protected void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
                //Yet another thread is finished:
                informUiAboutProgress(executor.getCompletedTaskCount(), listOfUrisToProcess.size());
            }
        }
    
    };
    
        @Override
        protected void terminated() {
            super.terminated();
            informUiThatWeAreDone();
        }
    
    }
  2. এবং আপনার থ্রেডগুলি শুরু করুন:

    private void startTheWork(){
        for (Uri uri : listOfUrisToProcess) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    doSomeHeavyWork(uri);
                }
            });
        }
        executor.shutdown(); //call it when you won't add jobs anymore 
    }

informUiThatWeAreDone();সমস্ত থ্রেড হয়ে গেলে আপনার অভ্যন্তরীণ পদ্ধতিটি যা করতে হবে তা করুন, উদাহরণস্বরূপ, ইউআই আপডেট করুন।

দ্রষ্টব্য:synchronized পদ্ধতিগুলি ব্যবহারের কথা ভুলে যাবেন না যেহেতু আপনি সমান্তরালভাবে আপনার কাজটি করেন এবং যদি আপনি synchronizedঅন্যের কাছ থেকে পদ্ধতি কল করার সিদ্ধান্ত নেন তবে খুব বেশি আগ্রহী হনsynchronized পদ্ধতি ! এটি প্রায়শই অচলাবস্থার দিকে পরিচালিত করে

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


0

আপনি সুইং ওয়ার্কারও ব্যবহার করতে পারেন, এতে বিল্ট-ইন সম্পত্তি পরিবর্তন সমর্থন রয়েছে। দেখুন addPropertyChangeListener () বা পেতে () একটি রাষ্ট্র পরিবর্তন শ্রোতা উদাহরণস্বরূপ পদ্ধতি।


0

থ্রেড ক্লাসের জন্য জাভা ডকুমেন্টেশন দেখুন। আপনি থ্রেডের অবস্থা পরীক্ষা করতে পারেন। আপনি যদি তিনটি থ্রেডকে সদস্যের ভেরিয়েবলগুলিতে রাখেন তবে তিনটি থ্রেডই একে অপরের রাজ্যগুলি পড়তে পারে।

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

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