目录
- 线程的两种执行方式:
- 1.execute()执行:
- 2.submit()执行:
- 两者区别:
- 线程池的两种关闭方式:
- 1.shutdown():
- 1.shutdownNow():
- 两者区别:
- 线程池的状态(5种):
- 线程池的状态转化图:
线程的两种执行方式:
1.execute()执行:
(new Runnable)无返回值的:
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadDemo58 {
public static void main(String[] args) {
// 创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, 5,
0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(5));
for (int i = 0; i < 11; i++) {
int finalI = i;
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("任务:" + finalI + ",线程名:" +
Thread.currentThread().getName());
}
});
}
}
}
2.submit()执行:
(new Runnable无返回值/new Callable有返回值的>
import java.util.Random;
import java.util.concurrent.*;
public class ThreadPoolDemo61 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, 5, 0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000)
);
// 返回返回值
Future<Integer> future = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(10);
System.out.println("线程池生成了随机数:" + num);
return num;
}
});
System.out.println("main 得到返回值:" + future.get());
}
}
两者区别:
- execute只能执行Runnable 任务,它是无返回值的; submit 它既能执行Runnable无返回值的任务,也能执行Callable有返回值的任务。
- execute执行任务如果有OM异常会将异常打印到控制台; 而submit执行任务出现了OM异常时不会打印异常。
线程池的两种关闭方式:
线程池的特征:线程池相比于线程来说是长生命周期,即使没有任务了,也会运行并等待任务。
1.shutdown():
import java.util.Random;
import java.util.concurrent.*;
public class ThreadDemo62 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, 5, 0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000)
);
// 返回返回值
Future<Integer> future = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(10);
System.out.println("线程池生成了随机数:" + num);
return num;
}
});
System.out.println("main 得到返回值:" + future.get());
// 关闭线程池
executor.shutdown();
}
}
1.shutdownNow():
import java.util.Random;
import java.util.concurrent.*;
public class ThreadDemo62 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, 5, 0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000)
);
// 返回返回值
Future<Integer> future = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(10);
System.out.println("线程池生成了随机数:" + num);
return num;
}
});
System.out.println("main 得到返回值:" + future.get());
// 关闭线程池
executor.shutdownNow();
}
}
两者区别:
(执行复杂任务时会体现出区别)
- shutdown():拒绝新任务加入,等待线程池中的任务队列执行完之后,再停止线程池。最后清空线程池中的线程。
- shutdownNow() :拒绝执行新任务,不会等待任务队列中的任务执行完成,就停止线程池。最后清空线程池中的线程。
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadDemo63 {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
10, 10, 0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000)
);
for (int i = 0; i < 100; i++) {
int finalI = i;
executor.submit(new Runnable() {
@Override
public void run() {
System.out.println(String.format("编号:%d,线程名:%s",
finalI, Thread.currentThread().getName()));
}
});
}
// 正常关闭
executor.shutdown();
// executor.shutdownNow();
}
}
线程池的状态(5种):
(注意: 线程池的状态不等于线程的状态(6种))
线程池的状态转化图:
从上图我们看到线程池总共存在5种状态,分别为:
- RUNNING:线程池创建之后的初始状态,这种状态下可以执行任务。
- SHUTDOWN:该状态下线程池不再接受新任务,但是会将工作队列中的任务执行结束。
- STOP:该状态下线程池不再接受新任务,但是不会处理工作队列中的任务,并且将会中断线程。
- TIDYING:该状态下所有任务都已终止,将会执行terminated()钩子方法。
- TERMINATED:执行完terminated()钩子方法之后。
注:线程池的状态只是给开发者使用的,对于客户机是不可见的。