在线程池实现的代码中存在疑问

时间:2013-01-23 14:39:10

标签: java multithreading threadpool

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

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

  2. 完成课程中的 _started 变量是什么?

  3. waitDone() waitBegin()完成课程)如何执行其功能? (如果你一步一步地解释这两种方法,那就太好了。)

  4. 代码如下。我正按照流程安排代码。

    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;
     }
    
    }
    

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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