--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.snmp/share/classes/com/sun/jmx/snmp/tasks/ThreadService.java Sun Aug 17 15:54:13 2014 +0100
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.jmx.snmp.tasks;
+
+import java.util.ArrayList;
+import com.sun.jmx.snmp.tasks.Task;
+import com.sun.jmx.snmp.tasks.TaskServer;
+
+/**
+ * This class implements a {@link com.sun.jmx.snmp.tasks.TaskServer} over
+ * a thread pool.
+ * <p><b>This API is a Sun Microsystems internal API and is subject
+ * to change without notice.</b></p>
+ **/
+public class ThreadService implements TaskServer {
+
+ public ThreadService(int threadNumber) {
+ if (threadNumber <= 0) {
+ throw new IllegalArgumentException("The thread number should bigger than zero.");
+ }
+
+ minThreads = threadNumber;
+ threadList = new ExecutorThread[threadNumber];
+
+ priority = Thread.currentThread().getPriority();
+ cloader = Thread.currentThread().getContextClassLoader();
+
+ }
+
+// public methods
+// --------------
+
+ /**
+ * Submit a task to be executed.
+ * Once a task is submitted, it is guaranteed that either
+ * {@link com.sun.jmx.snmp.tasks.Task#run() task.run()} or
+ * {@link com.sun.jmx.snmp.tasks.Task#cancel() task.cancel()} will be called.
+ * This implementation of TaskServer uses a thread pool to execute
+ * the submitted tasks.
+ * @param task The task to be executed.
+ * @exception IllegalArgumentException if the submitted task is null.
+ **/
+ public void submitTask(Task task) throws IllegalArgumentException {
+ submitTask((Runnable)task);
+ }
+
+ /**
+ * Submit a task to be executed.
+ * This implementation of TaskServer uses a thread pool to execute
+ * the submitted tasks.
+ * @param task The task to be executed.
+ * @exception IllegalArgumentException if the submitted task is null.
+ **/
+ public void submitTask(Runnable task) throws IllegalArgumentException {
+ stateCheck();
+
+ if (task == null) {
+ throw new IllegalArgumentException("No task specified.");
+ }
+
+ synchronized(jobList) {
+ jobList.add(jobList.size(), task);
+
+ jobList.notify();
+ }
+
+ createThread();
+ }
+
+ public Runnable removeTask(Runnable task) {
+ stateCheck();
+
+ Runnable removed = null;
+ synchronized(jobList) {
+ int lg = jobList.indexOf(task);
+ if (lg >= 0) {
+ removed = jobList.remove(lg);
+ }
+ }
+ if (removed != null && removed instanceof Task)
+ ((Task) removed).cancel();
+ return removed;
+ }
+
+ public void removeAll() {
+ stateCheck();
+
+ final Object[] jobs;
+ synchronized(jobList) {
+ jobs = jobList.toArray();
+ jobList.clear();
+ }
+ final int len = jobs.length;
+ for (int i=0; i<len ; i++) {
+ final Object o = jobs[i];
+ if (o!= null && o instanceof Task) ((Task)o).cancel();
+ }
+ }
+
+ // to terminate
+ public void terminate() {
+
+ if (terminated == true) {
+ return;
+ }
+
+ terminated = true;
+
+ synchronized(jobList) {
+ jobList.notifyAll();
+ }
+
+ removeAll();
+
+ for (int i=0; i<currThreds; i++) {
+ try {
+ threadList[i].interrupt();
+ } catch (Exception e) {
+ // TODO
+ }
+ }
+
+ threadList = null;
+ }
+
+// private classes
+// ---------------
+
+ // A thread used to execute jobs
+ //
+ private class ExecutorThread extends Thread {
+ public ExecutorThread() {
+ super(threadGroup, "ThreadService-"+counter++);
+ setDaemon(true);
+
+ // init
+ this.setPriority(priority);
+ this.setContextClassLoader(cloader);
+
+ idle++;
+ }
+
+ public void run() {
+
+ while(!terminated) {
+ Runnable job = null;
+
+ synchronized(jobList) {
+ if (jobList.size() > 0) {
+ job = jobList.remove(0);
+ if (jobList.size() > 0) {
+ jobList.notify();
+ }
+
+ } else {
+ try {
+ jobList.wait();
+ } catch (InterruptedException ie) {
+ // terminated ?
+ } finally {
+ }
+ continue;
+ }
+ }
+ if (job != null) {
+ try {
+ idle--;
+ job.run();
+ } catch (Exception e) {
+ // TODO
+ e.printStackTrace();
+ } finally {
+ idle++;
+ }
+ }
+
+ // re-init
+ this.setPriority(priority);
+ Thread.interrupted();
+ this.setContextClassLoader(cloader);
+ }
+ }
+ }
+
+// private methods
+ private void stateCheck() throws IllegalStateException {
+ if (terminated) {
+ throw new IllegalStateException("The thread service has been terminated.");
+ }
+ }
+
+ private void createThread() {
+ if (idle < 1) {
+ synchronized(threadList) {
+ if (jobList.size() > 0 && currThreds < minThreads) {
+ ExecutorThread et = new ExecutorThread();
+ et.start();
+ threadList[currThreds++] = et;
+ }
+ }
+ }
+ }
+
+
+// protected or private variables
+// ------------------------------
+ private ArrayList<Runnable> jobList = new ArrayList<Runnable>(0);
+
+ private ExecutorThread[] threadList;
+ private int minThreads = 1;
+ private int currThreds = 0;
+ private int idle = 0;
+
+ private boolean terminated = false;
+ private int priority;
+ private ThreadGroup threadGroup = new ThreadGroup("ThreadService");
+ private ClassLoader cloader;
+
+ private static long counter = 0;
+
+ private int addedJobs = 1;
+ private int doneJobs = 1;
+}