JavaSE-线程池(4)- JDK Executors提供的创建线程池的方法
newSingleThreadExecutor
该线程池只有一个线程处理任务
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
如下例:有8个任务被该线程池处理
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutorTest {
static class MyTask implements Runnable {
private int i;
public MyTask(int i) {
this.i = i;
}
@Override
public void run() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + " " + i);
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 1; i <= 8; i++) {
try {
executorService.execute(new MyTask(i));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
每个任务都是顺序执行的
Thread[pool-1-thread-1,5,main] 1
Thread[pool-1-thread-1,5,main] 2
Thread[pool-1-thread-1,5,main] 3
Thread[pool-1-thread-1,5,main] 4
Thread[pool-1-thread-1,5,main] 5
Thread[pool-1-thread-1,5,main] 6
Thread[pool-1-thread-1,5,main] 7
Thread[pool-1-thread-1,5,main] 8
newCachedThreadPool
缓存线程池,该线程池队列使用的是 SynchronousQueue(该队列不会存储任务) 且coreSize核心线程数为0,意味着新提交的任务会使用已创建的线程(该线程空闲时)或新建的线程处理,另外该线程池 keepAliveTime 为60秒,所以在60秒后如果线程空闲则会被回收
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
如下例,该线程池处理8个任务,每个任务执行时间为 1 秒,由于提交任务时前面的线程都没有空闲,所以这8个任务由8个不同线程处理
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadExecutorTest {
static class MyTask implements Runnable {
private int i;
public MyTask(int i) {
this.i = i;
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + " " + i);
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 1; i <= 8; i++) {
try {
executorService.execute(new MyTask(i));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Thread[pool-1-thread-1,5,main] 1
Thread[pool-1-thread-5,5,main] 5
Thread[pool-1-thread-7,5,main] 7
Thread[pool-1-thread-4,5,main] 4
Thread[pool-1-thread-3,5,main] 3
Thread[pool-1-thread-2,5,main] 2
Thread[pool-1-thread-8,5,main] 8
Thread[pool-1-thread-6,5,main] 6`
同样的程序,将睡眠时间注释掉
/*try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
那么程序执行的结果则有可能不同任务由同一个线程执行,如下(为了增加概率,将执行任务提高到了18):
Thread[pool-1-thread-2,5,main] 2
Thread[pool-1-thread-4,5,main] 4
Thread[pool-1-thread-1,5,main] 1
Thread[pool-1-thread-3,5,main] 3
Thread[pool-1-thread-5,5,main] 5
Thread[pool-1-thread-7,5,main] 7
Thread[pool-1-thread-9,5,main] 9
Thread[pool-1-thread-8,5,main] 8
Thread[pool-1-thread-8,5,main] 12
Thread[pool-1-thread-4,5,main] 17
Thread[pool-1-thread-2,5,main] 14
Thread[pool-1-thread-6,5,main] 6
Thread[pool-1-thread-9,5,main] 11
Thread[pool-1-thread-3,5,main] 16
Thread[pool-1-thread-7,5,main] 13
Thread[pool-1-thread-1,5,main] 10
Thread[pool-1-thread-5,5,main] 15
Thread[pool-1-thread-10,5,main] 18
newFixedThreadPool
拥有固定线程数的线程池,该线程池 corePoolSize 与 maximumPoolSize 大小一致:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
如下,该线程池处理8个任务,这8个任务都由2个线程执行
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPoolTest {
static final CountDownLatch countDownLatch = new CountDownLatch(8);
static class MyTask implements Runnable {
private int i;
public MyTask(int i) {
this.i = i;
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + " " + i);
countDownLatch.countDown();
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
ExecutorService executorService = Executors.newFixedThreadPool(2);
for (int i = 1; i <= 8; i++) {
try {
executorService.execute(new MyTask(i));
} catch (Exception e) {
e.printStackTrace();
}
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("耗时:" + (System.currentTimeMillis() - start));
}
}
Thread[pool-1-thread-1,5,main] 1
Thread[pool-1-thread-2,5,main] 2
Thread[pool-1-thread-2,5,main] 4
Thread[pool-1-thread-1,5,main] 3
Thread[pool-1-thread-2,5,main] 5
Thread[pool-1-thread-1,5,main] 6
Thread[pool-1-thread-1,5,main] 8
Thread[pool-1-thread-2,5,main] 7
耗时:4040