本文介绍了在线程池实现的代码中存在疑问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

花费大量时间使用线程池概念,并在Stackoverflow.com上阅读博客数量和发布问题的不同代码,现在我得到了这个概念的清晰图像。但与此同时,我发现代码存在一些疑问。

After spending lots of time with threadpool concepts and by reading different codes on numbers of blogs and posting questions on Stackoverflow.com, now I got clear image of this concept. But in the meanwhile, I found some doubts in code.


  1. pool.assign(new TestWorkerThread())时; 在TestThreadPool类中执行,它调用完成类中的
    done.workerBegin(); 方法,其中增加 _activeThreads 变量。但我认为, LOGICALLY 这是不正确的,因为如果线程数少于(在这种情况下为2)任务数量(在 TestThreadPool类中给出)(在这种情况5),它会不必要地递增 _activeThreads (即_activeThreads = 5)。

  1. When pool.assign(new TestWorkerThread()); executes in TestThreadPool Class, it callsdone.workerBegin(); method that is in Done Class, where it increments _activeThreads variable. But what I thinks is, LOGICALLY that is not correct because if number of threads are less(in this case 2) than number of tasks (given in TestThreadPool Class)(in this case 5), it increments _activeThreads (i.e., _activeThreads = 5) counts unnecessarily.

_started 变量在完成课程吗?

waitDone() waitBegin(如何)(在 Done Class 中)执行其功能? (如果你逐步解释这两种方法,那就太好了。)

How waitDone() and waitBegin() (in Done Class ) performs their functioning? (It is good if you explain these two methods step by step.)

代码如下。我根据其流程安排代码。

Code is as follows. I am arranging the codes according to its flow.

TestThreadPool类: -

package hitesh;

/**
 *
 * @author jhamb
 */

public class TestThreadPool {

 public static void main(String args[]) throws InterruptedException
 {
  ThreadPool pool = new ThreadPool(2);

  for (int i = 1;i <= 5;i++) {
   pool.assign(new TestWorkerThread());
  }
  System.out.println("All tasks are assigned");

  pool.complete();

  System.out.println("All tasks are done.");
 }
}

TestWorkerThread类: -

package hitesh;

/**
 *
 * @author jhamb
 */
/**
 * This class shows an example worker thread that can
 * be used with the thread pool. It demonstrates the main
 * points that should be included in any worker thread. Use
 * this as a starting point for your own threads.
 */

public class TestWorkerThread implements Runnable {
 static private int count = 0;
 private int taskNumber;
 protected Done done;

 /**
  *
  * @param done
  */
 TestWorkerThread()
 {
  count++;
  taskNumber = count;
  //System.out.println("tasknumber  --->  " + taskNumber);
 }

 public void run()
 {
  System.out.println("TWT run starts   -->  "  + this.toString());
  for (int i=0;i <= 100;i += 25) {
   System.out.println("Task number: " + taskNumber +
             ",percent complete = " + i );
   try {
    Thread.sleep((int)(Math.random()*500));
   } catch (InterruptedException e) {
   }
  }
  System.out.println("task for thread --> " + this.toString() + "   completed");
 }
}

ThreadPool类: -

package hitesh;

/**
 *
 * @author jhamb
 */
import java.util.*;


/*
 * This is the main class for the thread pool. You should
 * create an instance of this class and assign tasks to it.
 */

public class ThreadPool {

 protected Thread threads[] = null;

 Collection assignments = new ArrayList(3);

 protected Done done = new Done();


 public ThreadPool(int size) throws InterruptedException
 {
   threads = new WorkerThread[size];
   for (int i=0;i<threads.length;i++) {
    threads[i] = new WorkerThread(this);
    threads[i].start();
    System.out.println ("thread " + i + " started");
    threads[i].sleep(1000);
  }

 }

 public synchronized void assign(Runnable r)
 {
  done.workerBegin();
  assignments.add(r);
  System.out.println("Collection size --->   " + assignments.size() +   "  Thread can work on this");
  notify();
 }

 public synchronized Runnable getAssignment()
 {
  try {
   while ( !assignments.iterator().hasNext() )
    wait();

   Runnable r = (Runnable)assignments.iterator().next();
   assignments.remove(r);
   return r;
  } catch (InterruptedException e) {
   done.workerEnd();
   return null;
  }
 }

 public void complete()
 {
  done.waitBegin();
  done.waitDone();
 }

}

WorkerThread类: -

package hitesh;
import java.util.*;
/**
 *
 * @author jhamb
 */

/**
 * The worker threads that make up the thread pool.
 */
class WorkerThread extends Thread {
 /**
  * True if this thread is currently processing.
  */
 public boolean busy;
 /**
  * The thread pool that this object belongs to.
  */
 public ThreadPool owner;

 /**
  * The constructor.
  *
  * @param o the thread pool
  */
 WorkerThread(ThreadPool o)
 {
  owner = o;
 }

 /**
  * Scan for and execute tasks.
  */
    //@Override
 public void run()
 {
  System.out.println("Threads name : "+ this.getName() + "  working.....");
  Runnable target = null;

  do {
   System.out.println("enter in do while " + this.getName() );
   target = owner.getAssignment();
   System.out.println("GetAssignment k aage aa gya mai "  +  target);
   if (target!=null) {
    target.run();
    //target.
    owner.done.workerEnd();
   }
  } while (target!=null);
  System.out.println("do while finishes for "+ this.getName());
 }
}

完成课程: -

package hitesh;

/**
 *
 * @author jhamb
 */
/**
 *
 * This is a thread pool for Java, it is
 * simple to use and gets the job done. This program and
 * all supporting files are distributed under the Limited
 * GNU Public License (LGPL, http://www.gnu.org).
 *
 * This is a very simple object that
 * allows the TheadPool to determine when
 * it is done. This object implements
 * a simple lock that the ThreadPool class
 * can wait on to determine completion.
 * Done is defined as the ThreadPool having
 * no more work to complete.
 *
 * Copyright 2001 by Jeff Heaton
 *
 * @author Jeff Heaton (http://www.jeffheaton.com)
 * @version 1.0
 */
public class Done {

 /**
  * The number of Worker object
  * threads that are currently working
  * on something.
  */
 private int _activeThreads = 0;

 /**
  * This boolean keeps track of if
  * the very first thread has started
  * or not. This prevents this object
  * from falsely reporting that the ThreadPool
  * is done, just because the first thread
  * has not yet started.
  */
 private boolean _started = false;
 /**
  * This method can be called to block
  * the current thread until the ThreadPool
  * is done.
  */

 synchronized public void waitDone()
 {
  try {
   while ( _activeThreads>0 ) {
    wait();
   }
  } catch ( InterruptedException e ) {
  }
 }
 /**
  * Called to wait for the first thread to
  * start. Once this method returns the
  * process has begun.
  */

 synchronized public void waitBegin()
 {
  try {
   while ( !_started ) {
    wait();
   }
  } catch ( InterruptedException e ) {
  }
 }


 /**
  * Called by a Worker object
  * to indicate that it has begun
  * working on a workload.
  */
 synchronized public void workerBegin()
 {
  _activeThreads++;
  _started = true;
  notify();
 }

 /**
  * Called by a Worker object to
  * indicate that it has completed a
  * workload.
  */
 synchronized public void workerEnd()
 {
  _activeThreads--;
  notify();
 }

 /**
  * Called to reset this object to
  * its initial state.
  */
 synchronized public void reset()
 {
  _activeThreads = 0;
 }

}

请帮忙。提前致谢。寻找你的回应。

Please help. Thanks in advance. Looking for your kind response.

推荐答案

现在我完全理解整个代码。如果您在此代码中发现任何疑问,那么您可以询问。

Now I understand that whole code very perfectly. If you find any doubts in this code, then you can ask.

在阅读了很多内容后,我的问题的答案如下。

Answers of my questions are as follows after reading a lot on this.


  1. 是的,你是对的,这在逻辑上是错误的。它更好,如果它是 _activeTasks 。当线程池没有更多工作时,它用于终止所有线程,因为waitDone()函数仅在 _activeTasks< = 0 时成功执行。

  1. Yes, you are right, it is logically wrong. Its better, if it would be _activeTasks . It is used to kill all the threads , when threadpool have no more work because waitDone() function executes successfully only when _activeTasks <= 0.

此变量用于 waitBegin()方法。每当任何任务开始时,它都会由 TRUE 更新_started,意味着用户分配的任务现在由线程处理,意味着线程开始处理这些任务。如果用户未给出任务,则所有线程仍处于活动状态,并等待任务。这是在这里使用这个变量。

This Variable is used in waitBegin() method. Whenever any tasks starts, it updates _started by TRUE, means the tasks that are assigned by users is now in processing by threads, means threads starts working on these tasks. If tasks is not given by user, then all threads are still active , and waiting for tasks. This is the use of this variable here.

当线程开始处理任务时,waitBegin()方法成功执行,因为在这种情况下只有_started变为true。否则,线程会继续等待某些任务。 waitDone()仅在_activeTasks变为零时才成功执行,因为这是线程池没有任何工作要执行的唯一情况,这意味着线程池完成其工作。否则,它会一直等到所有任务完成,意味着等到_activeTasks变为 ZERO

waitBegin() method executes successfully when threads starts working on tasks, because in that case only _started become true. Otherwise, threads keep on waiting for some tasks. waitDone() executes successfully only when _activeTasks become Zero, because this is the only situation when threadpool don't have any work to perform, means threadpool completes its work. Otherwise, it keep waiting until all tasks finish, means it waits until when _activeTasks becomes ZERO

这篇关于在线程池实现的代码中存在疑问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-16 02:20