- 线程池两种执行方式:
(1)execute 执行(new Runnable)无返回值
(2)submit 执行 (new Runnable
无返回值/new Callable 有返回值的)
都用Futrue进行执行任务的接收
public class ThreadPoolDemo8 {
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);//生成0-9随机数
System.out.println("线程池生成了随机数:"+num);
return num;
}
});
System.out.println("main得到返回值:"+future.get());
}
}
执行方法区别:
1. execute 只能执行Runnable 任务,它是无返回值的;
submit 它既能执行Runnable 无返回值的任务,也能执行Callable 有返回值的任务。
2. execute执行任务如果有OOM异常会将异常打印到控制台;
submit 执行任务出现了 OOM异常时不会打印异常。线程池的特征:相比于线程来说是长生命周期,即使没有任务也会运行并且等待任务
(1)shutdown:拒绝新任务加入,等待线程池中任务队列执行完成之后,再停止线程池,下一步是清空线程池中的线程。
(2)shutdownNow:拒绝新任务加入,不会等待线程池中任务队列中的任务执行完成,就停止线程池,下一步是清空线程池中的线程
-线程池状态
注意:线程池状态(5种)不等于线程状态(6种)
从上图我们看到线程池总共存在5种状态,分别为:
- RUNNING: 线程池创建之后的初始状态,这种状态下可以执行任务。
- SHUTDOWN:该状态下线程池不再接受新任务,但是会将工作队列中的任务执行结束。
- STOP: 该状态下线程池不再接受新任务,但是不会处理工作队列中的任务,并且将会中断线程。
- TIDYING: 该状态下所有任务都已终止,将会执行terminated() 方法。
- TERMINATED:执行完terminated() 方法之后。
线程池的状态只是给开发者使用的,对于客户机是不可见的。
线程不安全的解决方案:
- CPU抢占式执行[ 不可行]
2.加锁(synchronized、 Lock)
3.私有变量(ThreadLocal 线程本地变量)
ThreadLoca l线程级别的私有变量
与任务级别的私有变量是完全不同
需求1:使用最高效的方式实现两个Date (时间类型)的格式化?
mm: SS
//需求1:使用最高效的方式实现两个Date (时间类型)的格式化?
// * mm: SS
public class ThreadPoolDemo11 {
public static void main(String[] args) {
// Date date = new Date(1000);//传值之后表示从计算机元年开始之后的1秒
// System.out.println("时间按格式化之前:" + date);
// SimpleDateFormat dateFormat = new SimpleDateFormat("" +
// "yyyy-MM-dd hh:mm:ss");
// String result = dateFormat.format(date);
// System.out.println("格式化之后:" + result);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
Date date = new Date(1000);
//执行时间格式化并打印结果
myFormatTime(date);
}
});
t1.start();
Thread t2 = new Thread(new Runnable()