java对线程池实现代码的质疑
花了大量时间研究线程池概念,阅读了大量博客上的不同代码,并在Stackoverflow上发布了问题。现在我对这个概念有了清晰的认识。但与此同时,我在代码中发现了一些疑问
当游泳时。分配(新TestWorkerThread())在TestThreadPool类中执行,它调用 完成。workerBegin()方法,该方法位于完成类,在该类中它增加了\u activeThreads变量。但我认为,在逻辑上是不正确的,因为如果线程数(在本例中为2)小于任务数(在TestThreadPool类中为5),那么它会不必要地增加_activeThreads(即_activeThreads=5)计数
\u start变量在完成类中做什么
waitDone()和waitBegin()(在Done类中)如何执行其功能?(如果你能一步一步地解释这两种方法就好了。)
代码如下。我正在按照流程安排代码
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");
}
}
线程池类:-
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 楼答案
现在我完全理解了整个代码。如果你在这段代码中发现任何疑问,那么你可以问
在阅读了大量关于这方面的内容后,我的问题的答案如下
是的,你是对的,这在逻辑上是错误的。如果是\u activeTasks就更好了。当threadpool没有更多工作时,它用于杀死所有线程,因为waitDone()函数只有在\u activeTasks<;=0
此变量用于waitBegin()方法。每当任何任务启动时,它都会更新_startedbyTRUE,这意味着用户分配的任务现在正在由线程处理,这意味着线程开始处理这些任务。如果任务不是由用户给定的,那么所有线程仍然处于活动状态,并等待任务。这里就是这个变量的用法
当线程开始处理任务时,waitBegin()方法会成功执行,因为在这种情况下,只有_start变为true。否则,线程会继续等待某些任务。waitDone()只有在_activeTasks变为零时才能成功执行,因为这是threadpool没有任何工作要执行的唯一情况,这意味着threadpool完成了它的工作。否则,它会一直等到所有任务完成,这意味着它会等到_activeTasks变为零