这是我在学习线程池过程中边码的代码,涉及如何按阿里标准创建线程池,什么情况会出现Exception。
知识背景
代码
请认真看注释
package Chapter3.AboutThreadPool;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.junit.Test;
import java.util.concurrent.*;
public class T1 {
// Executors.newFixedThreadPool source code use ThreadPoolExecutor :
// public static ExecutorService newFixedThreadPool(int nThreads) {
// return new ThreadPoolExecutor(nThreads, nThreads,
// 0L, TimeUnit.MILLISECONDS,
// new LinkedBlockingQueue<Runnable>());
// }
// ExecutorService es1 = Executors.newFixedThreadPool(1);
final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1);
final ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Orders-%d").setDaemon(true).build();
ExecutorService es = new ThreadPoolExecutor(1, 1, 0L,
TimeUnit.MILLISECONDS, queue, threadFactory);
// ExecutorService es = new ThreadPoolExecutor(6, 10, 0L,
// TimeUnit.MILLISECONDS, queue, threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
/**
* if ExecutorService use AbortPolicy, Exception raised: <br/>
* “RejectedExecutionException: <br/>
* FutureTask rejected from ThreadPoolExecutor <br/>
* [Running, pool size = 10, active threads = 10, queued tasks = 5, completed tasks = 0]” <br/>
* <br/>
* if ExecutorService use CallersRunsPolicy, no exception. <br/>
* If no resources available, the next set of tasks will block to wait until the previous set finish. <br/>
*
*/
@Test
public void test1() {
for (int i = 0; i < 1000000; i++) {
es.submit(()->{
try {
Thread.sleep(5000);
System.out.println("Thread " + Thread.currentThread().getId() + ": " + "finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("Task " + i + "submited");
}
es.shutdown();
}
/**
* raise RejectedExecutionException
*/
@Test
public void test2() {
for (int i = 0; i < 1000000; ++i) {
int finalI = i;
es.submit(()->{
try {
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName() + " processing: " + finalI);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("Task " + i + " submitted");
}
}
/**
* 为什么这里不会报错RejectedExecutionException???<br/>
* 因为语句:res.get()导致了线程的阻塞执行,线程1没执行完,不会开始提交线程2,所以最后看起来像是同步执行,并且也永远不会报错。因为每次只有一个线程在同时执行。
*/
@Test
public void test3() {
for (int i = 0; i < 1000000; ++i) {
int finalI = i;
Future<Boolean> res = es.submit(new Callable<Boolean>() {
@Override
public Boolean call() {
try {
String name = Thread.currentThread().getName();
Thread.sleep(5000);
System.out.println(name + " processing: " + finalI);
} catch (Exception e) {
e.printStackTrace();
}
return finalI % 2 == 0;
}
});
try {
System.out.println(res.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* RejectedExecutionException
*/
@Test
public void test4() {
for (int i = 0; i < 1000000; ++i) {
int finalI = i;
Future<Boolean> res = es.submit(new Callable<Boolean>() {
@Override
public Boolean call() {
try {
String name = Thread.currentThread().getName();
Thread.sleep(5000);
System.out.println(name + " processing: " + finalI);
} catch (Exception e) {
e.printStackTrace();
}
return finalI % 2 == 0;
}
});
System.out.println("Task " + i + " submitted");
}
}
}