1,
/*******************************************************************************
* Copyright (c) 2016, 2016 Technologies Corporation.
******************************************************************************/
package test.yang.thread;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @Version 1.0
* @Author uu.yang@.com
* @Created Jan 13, 2016 6:00:02 PM
* @Description
* <p>
* newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool实际上也是调用了ThreadPoolExecutor, 只不过参数都已配置好了。
* newFixedThreadPool创建的线程池corePoolSize和maximumPoolSize值是相等的,它使用的LinkedBlockingQueue;
* newSingleThreadExecutor将corePoolSize和maximumPoolSize都设置为1,也使用的LinkedBlockingQueue;
* newCachedThreadPool将corePoolSize设置为0,将maximumPoolSize设置为Integer.MAX_VALUE,使用的SynchronousQueue,也就是说来了任务就创建线程运行,当线程空闲超过60秒,就销毁线程。
* @Modification
* <p>
* Date Author Version Description
* <p>
* Jan 13, 2016 oo.yang@.com 1.0 create file
*/
public class TestThreadPool {
public static void main(final String[] args) {
final TestThreadPool testThreadPool = new TestThreadPool();
testThreadPool.testThreadPoolExecutor();
}
private void testCachedThreadPool() {
/* 线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。 */
final ExecutorService service = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(index * 1000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(index);
}
});
}
}
private void testFixedThreadPool() {
/* 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 */
final ExecutorService service = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
service.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
});
}
/*
* 因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
* 定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()
*/
}
private void testScheduledThreadPool() {
/* 创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下: */
final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("delay 3 seconds");
}
}, 3, TimeUnit.SECONDS);
}
private void testSingleThreadPool() {
/* 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下: */
final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
@Override
public Thread newThread(final Runnable r) {
final Thread thread = new Thread(r);
thread.setName("测试单线程");
return thread;
}
});
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
private void testThreadPoolExecutor() {
/*
* 创建线程池(没有任务不创建线程),超过5个就把多余的放缓存队列中,线程池最多一共10个,空闲线程空闲200ms就停止掉 。
* 当开15个任务时,就把10个放线程池,5个放缓存队列中;当任务超过15个就会报错
*/
final ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5));
for (int i = 0; i < 15; i++) {
final MyTask myTask = new MyTask(i);
executor.execute(myTask);
System.out.println("\n已添加第 " + i + " 个task");
System.out.println("线程池中线程数目:" + executor.getPoolSize() + ",队列中等待执行的任务数目:" + executor.getQueue().size() + ",已执行玩别的任务数目:"
+ executor.getCompletedTaskCount());
}
executor.shutdown();
}
}
class MyTask implements Runnable {
private final int taskIndex;
public MyTask(final int index) {
taskIndex = index;
}
@Override
public void run() {
System.out.println("------------------正在执行task " + taskIndex);
try {
Thread.sleep(5000);
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("------------------task " + taskIndex + "执行完毕");
}
}
2,
3,