ThreadGroup Thread Runnable

import java.util.LinkedList;

/**
    A thread pool is a group of a limited number of threads that
    are used to execute tasks.
*/
public class ThreadPool extends ThreadGroup {

    private boolean isAlive;
    private LinkedList<Runnable> taskQueue;
    private int threadID;
    private static int threadPoolID;

    /**
        Creates a new ThreadPool.
        @param numThreads The number of threads in the pool.
    */
    public ThreadPool(int numThreads) {
        super("ThreadPool-" + (threadPoolID++));
        setDaemon(true);

        isAlive = true;

        taskQueue = new LinkedList<Runnable>();
        for (int i=0; i<numThreads; i++) {
            new PooledThread().start();
        }
    }


    /**
        Requests a new task to run. This method returns
        immediately, and the task executes on the next available
        idle thread in this ThreadPool.
        <p>Tasks start execution in the order they are received.
        @param task The task to run. If null, no action is taken.
        @throws IllegalStateException if this ThreadPool is
        already closed.
    */
    public synchronized void runTask(Runnable task) {
        if (!isAlive) {
            throw new IllegalStateException();
        }
        if (task != null) {
            taskQueue.add(task);
            notify();
        }

    }


    protected synchronized Runnable getTask()
        throws InterruptedException
    {
        while (taskQueue.size() == 0) {
            if (!isAlive) {
                return null;
            }
            wait();
        }
        return (Runnable)taskQueue.removeFirst();
    }


    /**
        Closes this ThreadPool and returns immediately. All
        threads are stopped, and any waiting tasks are not
        executed. Once a ThreadPool is closed, no more tasks can
        be run on this ThreadPool.
    */
    public synchronized void close() {
        if (isAlive) {
            isAlive = false;
            taskQueue.clear();
            interrupt();
        }
    }


    /**
        Closes this ThreadPool and waits for all running threads
        to finish. Any waiting tasks are executed.
    */
    public void join() {
        // notify all waiting threads that this ThreadPool is no
        // longer alive
        synchronized (this) {
            isAlive = false;
            notifyAll();
        }

        // wait for all threads to finish
        Thread[] threads = new Thread[activeCount()];
        int count = enumerate(threads);
        for (int i=0; i<count; i++) {
            try {
                threads[i].join();
            }
            catch (InterruptedException ex) { }
        }
    }


    /**
        A PooledThread is a Thread in a ThreadPool group, designed
        to run tasks (Runnables).
    */
    private class PooledThread extends Thread {


        public PooledThread() {
            super(ThreadPool.this,
                "PooledThread-" + (threadID++));
        }


        public void run() {
            while (!isInterrupted()) {

                // get a task to run
                Runnable task = null;
                try {
                    task = getTask();
                }
                catch (InterruptedException ex) { }

                // if getTask() returned null or was interrupted,
                // close this thread by returning.
                if (task == null) {
                    return;
                }

                // run the task, and eat any exceptions it throws
                try {
                    task.run();
                }
                catch (Throwable t) {
                    uncaughtException(this, t);
                }
            }
        }
    }
}
public class ThreadPoolTest {

    public static void main(String[] args) {
        int numTasks = 8;
        int numThreads = 4;

        // create the thread pool
        ThreadPool threadPool = new ThreadPool(numThreads);

        // run example tasks
        for (int i=0; i<numTasks; i++) {
            threadPool.runTask(createTask(i));
        }

        // close the pool and wait for all tasks to finish.
        threadPool.join();
    }


    /**
        Creates a simple Runnable that prints an ID, waits 500
        milliseconds, then prints the ID again.
    */
    private static Runnable createTask(final int taskID) {
        return new Runnable() {
            public void run() {
            	System.out.println(Thread.currentThread().getThreadGroup().getName()); 
                System.out.println("Task " + taskID + ": start");

                // simulate a long-running task
                try {
                    Thread.sleep(500);
                }
                catch (InterruptedException ex) { }

                System.out.println("Task " + taskID + ": end");
            }
        };
    }

}

 

1 void java.lang.Thread.start()
Starts the new Thread of execution. The run() method of the receiver will be called by the receiver Thread itself (and not the Thread calling start()).

2 void java.lang.Thread.run()
Calls the run() method of the Runnable object the receiver holds. If no Runnable is set, does nothing

3 void java.lang.Object.notify()
Causes one thread which is waiting on the receiver to be made ready to run. This does not guarantee that the thread will immediately run. The method can only be invoked by a thread which owns the receiver's monitor.
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.

This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:

•By executing a synchronized instance method of that object.
•By executing the body of a synchronized statement that synchronizes on the object.
•For objects of type Class, by executing a synchronized static method of that class.
Only one thread at a time can own an object's monitor.

4 int java.lang.ThreadGroup.enumerate(Thread[] threads)

Copies an array with all Threads which are children of the receiver (directly or indirectly) into the array threads passed as parameters. If the array passed as parameter is too small no exception is thrown - the extra elements are simply not copied.
How to copy two threadgroup into one array?

public class Test {
	public static void main(String args[]) {
		ThreadGroup groupA = new ThreadGroup("Group A");
		ThreadGroup groupB = new ThreadGroup("Group B");
		NewThread ob1 = new NewThread("One", groupA);
		NewThread ob2 = new NewThread("Two", groupA);
		NewThread ob3 = new NewThread("Three", groupB);
		NewThread ob4 = new NewThread("Four", groupB);
		System.out.println("\nHere is output from list():"+new Test());
		groupA.list();//Outputs to System.out a text representation of the hierarchy of Threads and ThreadGroups in the receiver (and recursively). 
					  //Proper indentation is done to suggest the nesting of groups inside groups and threads inside groups.
		groupB.list();
		System.out.println();
		System.out.println("Suspending Group A");
		Thread tga[] = new Thread[groupA.activeCount()+groupB.activeCount()];//Returns the number of Threads which are children of the receiver, directly or indirectly.
		groupA.enumerate(tga); // get threads in group
		groupB.enumerate(tga);
		for (int i = 0; i < tga.length; i++) {
			((NewThread) tga[i]).mysuspend(); // suspend each thread
		}
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			System.out.println("Main thread interrupted.");
		}
		System.out.println("Resuming Group A");
		for (int i = 0; i < tga.length; i++) {
			((NewThread) tga[i]).myresume(); // resume threads in group}
			// wait for threads to finish
			try {
				System.out.println("Waiting for threads to finish.");
				ob1.join();
				ob2.join();
				ob3.join();
				ob4.join();
			} catch (Exception e) {
				System.out.println("Exception in Main thread");
			}
			System.out.println("Main thread exiting.");
		}

		System.out.println(Thread.currentThread().getThreadGroup().getName());
	}
}

class NewThread extends Thread {
	boolean suspendFlag;

	NewThread(String threadname, ThreadGroup tgOb) {
		super(tgOb, threadname);
		System.out.println("New thread: " + this);
		suspendFlag = false;
		start(); // Start the thread
	}

	// This is the entry point for thread.
	public void run() {
		try {
			for (int i = 5; i > 0; i--) {
				System.out.println("run method "+getName() + ": " + i);
				Thread.sleep(1000);
				synchronized (this) {
					while (suspendFlag) {
						wait();
					}
				}
			}
		} catch (Exception e) {
			System.out.println("Exception in " + getName());
		}
		System.out.println(getName() + " exiting."+this);
	}

	void mysuspend() {
		suspendFlag = true;
	}

	synchronized void myresume() {
		suspendFlag = false;
		notify();
	}
}

 

posted on 2013-03-05 21:58  jnuyao  阅读(238)  评论(0编辑  收藏  举报