package cn.smallbug.jdk.concurrent.exe;
import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.DiscardPolicy;
import java.util.concurrent.TimeUnit;
import org.junit.Before;
import org.junit.Test;
public class TestThreadPoolExecutor {
private ThreadPoolExecutor pool = null;
@Before
public void before() {
this.pool = new ThreadPoolExecutor(//
/**
* corePoolSize(线程池的根本大小):<br />
* 当提交一个义务到线程池时,线程池会创立一个线程来履行义务,
* 即便其他空闲的根本线程能够履行新义务也会创立线程,等到须要履行的义务数大于线程池根本大小时就不再创立。
* 如果调用了线程池的prestartAllCoreThreads办法,线程池会提早创立并启动所有根本线程。
*/
10,
/**
* maximumPoolSize(线程池最大大小):<br />
* 线程池许可创立的最大线程数。如果队列满了,并且已创立的线程数小于最大线程数,则线程池会再创立新的线程履行义务。
* 值得注意的是如果应用了无界的义务队列这个参数就没甚么后果。
*/
20,
/**
* keepAliveTime(线程运动坚持时光):<br />
* 线程池的工作线程空闲后,坚持存活的时光。
*/
1000,
/**
* TimeUnit(线程运动坚持时光的单位):<br />
* 可选:<br />
* <ul>
* <li>单位有天(DAYS)</li>
* <li>小时(HOURS)</li>
* <li>分钟(MINUTES)</li>
* <li>毫秒(MILLISECONDS)</li>
* <li>微秒(MICROSECONDS, 千分之一毫秒)</li>
* <li>毫微秒(NANOSECONDS, 千分之一微秒)</li>
* </ul>
*/
TimeUnit.MILLISECONDS, // 表现线程运动坚持时光为1000ms,
/**
* runnableTaskQueue(义务队列):<br />
* 用于保留期待履行的义务的阻塞队列。可以选择以下几个阻塞队列:
* <ul>
* <li><b>ArrayBlockingQueue:</b>是一个基于数组构造的有界阻塞队列,此队列按
* FIFO(先进先出)原则对元素进行排序。</li>
* <li><b>LinkedBlockingQueue:</b>一个基于链表构造的阻塞队列,此队列按FIFO (先进先出)
* 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂办法Executors.
* newFixedThreadPool()应用了这个队列。</li>
* <li><b>SynchronousQueue:</b>
* 一个不存储元素的阻塞队列。每一个插入操作必需等到另外一个线程调用移除操作,
* 否则插入操作一直处于阻塞状况,吞吐量通常要高于LinkedBlockingQueue,静态工厂办法Executors.
* newCachedThreadPool应用了这个队列。</li>
* <li><b>PriorityBlockingQueue:</b>一个具有优先级的无穷阻塞队列。</li>
* </ul>
*/
new ArrayBlockingQueue<Runnable>(100),
/**
* ThreadFactory:<br />
* 用于设置创立线程的工厂,可以通过线程工厂给每一个创立出来的线程设置更成心义的名字,Debug和定位问题时非常又赞助。
*/
// new CreateThread(),
/**
* RejectedExecutionHandler(饱和策略):<br />
* 当队列和线程池都满了,解释线程池处于饱和状况,那末必需采用一种策略处置提交的新义务。
* 这个策略默许情形下是AbortPolicy,表现没法处置新义务时抛出异常。以下是JDK1.5供给的四种策略
* <ul>
* <li>CallerRunsPolicy:只用调用者所在线程来运行义务。</li>
* <li>DiscardOldestPolicy:抛弃队列里最近的一个义务,并履行当前义务。</li>
* <li>DiscardPolicy:不处置,抛弃掉。</li>
* <li>固然也能够依据运用处景须要来实现RejectedExecutionHandler接口自定义策略。
* 如记载日志或持久化不能处置的义务。</li>
* </ul>
*/
new DiscardPolicy()//
);
}
/**
* 线程池在创立时如果指定义务工厂execute的义务将无效
*
* @timestamp Mar 19, 2016 3:08:56 PM
*/
@Test
public void testExecute() {
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(2 + 2);
}
});
}
/**
* 线程池在创立时如果指定义务工厂execute的义务将无效
*
* @timestamp Mar 19, 2016 3:11:21 PM
*/
@Test
public void testSubmit() {
int i = 100;
while (i-- > 0) {
pool.submit(//
new Callable<Serializable>() {
@Override
public Serializable call() throws Exception {
return 2 + 2;
}
}//
);
}
Future<Serializable> result = pool.submit(//
new Callable<Serializable>() {
@Override
public Serializable call() throws Exception {
return 2 + 2;
}
}//
);
Serializable s = null;
try {
s = (int) result.get();
} catch (InterruptedException e) {
// 处置中止异常
e.printStackTrace();
} catch (ExecutionException e) {
// 处置没法履行义务异常
e.printStackTrace();
} finally {
stastic(pool);
/**
* 1、将线程池的状况设置成SHUTDOWN状况<br />
* 2、然后中止所有无正在履行义务的线程
*/
pool.shutdown();
/**
* 1、将线程池的状况设置成STOP<br />
* 2、遍历线程池中的工作线程<br />
* 3、逐一调用线程的interrupt办法来中止线程(没法响应中止的义务可能永久没法终止)<br />
* 4、返回期待履行义务的列表
*/
// pool.shutdownNow();
/**
* 只要调用了这两个关闭办法的其中一个,isShutdown办法就会返回true<br />
* 当所有的义务都已关闭后,才表现线程池关闭胜利,这时候调用isTerminaed办法会返回true<br />
* 通常调用shutdown来关闭线程池,如果义务没必要定要履行完,则可以调用shutdownNow
*/
}
System.out.println(s);
}
/**
* 通过继承线程池并重写线程池的 <br />
* beforeExecute <br />
* afterExecute <br />
* terminated <br />
* 办法,可以在义务履行前, 履行后和线程池关闭前干一些事情。如监控义务的平均履行时光,最大履行时光和最小履行时光等。
*
* @timestamp Mar 19, 2016 3:37:29 PM
* @param pool2
*/
private void stastic(ThreadPoolExecutor pool) {
System.out.println("current cpu num -> " + Runtime.getRuntime().availableProcessors());
System.out.println("线程池须要履行的义务数目 -> " + pool.getTaskCount());
System.out.println("线程池在运行进程中已完成的义务数目。小于或等于taskCount -> " + pool.getCompletedTaskCount());
System.out.println("线程池曾创立过的最大线程数目 -> " + pool.getLargestPoolSize());
System.out.println("线程池的线程数目。如果线程池不烧毁的话,池里的线程不会主动烧毁,所以这个大小只增不减 -> " + pool.getPoolSize());
System.out.println("获得运动的线程数 -> " + pool.getActiveCount());
}
/**
* 工作义务创立工厂
*
* @timestamp Mar 19, 2016 3:01:24 PM
* @author smallbug
*/
class CreateThread implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
return new Thread() {
@Override
public void run() {
System.out.println(1 + 1);
}
};
}
}
}
package cn.smallbug.jdk.concurrent.exe;
import