可以通过executors,threadpoolexecutors两种方式七种方法进行创建
创建一个指定线程池数量的线程池,此方法内创建了线程数量位5的线程池,在测试的时候可以通过更改Executors.newFixedThreadPool内传入的参数进行控制要创建的线程池内的线程数量
public void test(){
ExecutorService executorService = Executors.newFixedThreadPool(5);
Runnable run = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在工作......");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for (int i = 0; i < 10; i++) {
executorService.execute(run);
}
}
通过此种方法Executors.newCachedThreadPool()可以创建一个可缓存的线程池,从示例代码中可以看出,我们开启了一百个任务,那么它会相应的开启一百个线程,可以弹性的根据任务情况创建相应的线程
public void test(){
ExecutorService executorService = Executors.newCachedThreadPool();
Runnable run = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在工作......");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for (int i = 0; i < 100; i++) {
executorService.execute(run);
}
}
创建单个延时线程
public void test(){
//创建延时线程池
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
//创建执行任务,并记录任务开始执行时间
Runnable run = new Runnable() {
@Override
public void run() {
System.out.println("任务开始时间"+new Date());
System.out.println(Thread.currentThread().getName()+"正在工作......");
}
};
//记录线程开始时间
System.out.println("线程开启时间"+new Date());
//创建线程,添加要执行的任务,间隔的时间位2,单位为秒
scheduledExecutorService.schedule(run,2, TimeUnit.SECONDS);
}
创建单个线程的线程池,通过结果我们可以看出,只有一个线程在工作
public void test(){
ExecutorService executorService = Executors.newSingleThreadExecutor();
Runnable run = new Runnable() {
@Override
public void run() {
System.out.println("任务开始时间"+new Date());
System.out.println(Thread.currentThread().getName()+"正在工作......");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
executorService.execute(run);
executorService.execute(run);
executorService.execute(run);
executorService.execute(run);
}
创建可以执行延迟任务的多个线程的线程池,与上述的单个线程的延迟执行对比,这个可以创建多个线程,通过结果可以看出,从打开线程到任务开始执行,确实经过了三秒的时间
public void test(){
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
Runnable run = new Runnable() {
@Override
public void run() {
System.out.println("任务开始时间"+new Date());
System.out.println(Thread.currentThread().getName()+"正在工作......");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
System.out.println("线程开始时间"+new Date());
scheduledExecutorService.schedule(run,3,TimeUnit.SECONDS);
scheduledExecutorService.schedule(run,3,TimeUnit.SECONDS);
scheduledExecutorService.schedule(run,3,TimeUnit.SECONDS);
}
抢占式线程池,经过查资料了解,这种类型的线程是jdk1.8的新特性中的,总体来说经过平均分配各个线程的任务,在自己的任务执行完成以后,会去其他未执行完成的任务队列抓取任务,这样可以相应的提高执行效率
public void test(){
ExecutorService executorService = Executors.newWorkStealingPool();
Runnable run = new Runnable() {
@Override
public void run() {
System.out.println("任务开始时间"+new Date());
System.out.println(Thread.currentThread().getName()+"正在工作......");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for (int i = 0; i < 100; i++) {
executorService.execute(run);
}
}
使用原始的线程池创建方式,可以很灵活的对线程池的各项参数进行设定
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 10, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
// 执行任务
for (int i = 0; i < 10; i++) {
final int index = i;
threadPool.execute(() -> {
System.out.println(index + " 被执行,线程名:" + Thread.currentThread().getName());
});
}