线程池常用的概念:
1. Threads和runnable
2.runnable和callable
3.callable和Future
4.ExcutorService.invokeAll,ExcutorService.invokeAny
5.Excutors.newScheculedThreadPool()
6.ScheduledService.scheduleWithFixedRate() 固定频率
7.ScheduledService.scheduleWithFixedDelay() 固定间隔
Java 5
初次引入了Concurrency API,并在随后的发布版本中不断优化和改进。这篇文章的大部分概念也适用于老的版本。我的代码示例主要聚焦在Java 8
上,并大量适用 lambda
表达式和一些新特性。如果你还不熟悉 lambda
表达式,建议先阅读 Java 8 Tutorial。
Threads
和 Runnables
所有现代操作系统都是通过进程
和线程
来支持并发的。进程
通常是相互独立运行的程序实例。例如,你启动一个 Java
程序,操作系统会产生一个新的进程
和其他程序并行运行。在这些进程
中可以利用线程
同时执行代码。这样我们就可以充分利用 CPU
。
Java
从 JDK 1.0
开始就支持线程
。在开始一个新线程
之前,必须先指定运行的代码,通常称为 Task
。下面是通过实现 Runnable
接口来启动一个新线程的例子:
Runnable task = () -> {
String threadName = Thread.currentThread().getName();
System.out.println("Hello " + threadName);
};
task.run();
Thread thread = new Thread(task);
thread.start();
System.out.println("Done!");
复制代码
由于 Runnable
是一个函数式
接口,我们可以使用 lambda
表达式来打印线程的名字到控制台。我们直接在主线程上执行Runnable
,然后开始一个新线程。在控制台你将看到这样的结果:
Hello main
Hello Thread-0
Done!
复制代码
或者:
Hello main
Done!
Hello Thread-0
复制代码
由于是并发
执行,我们无法预测 Runnable
是在打印 Done
之前还是之后调用,顺序不是不确定的,因此并发编程
成为大型应用程序开发中一项复杂的任务。
线程也可以休眠一段时间,例如下面的例子:
Runnable runnable = () -> {
try {
String name = Thread.currentThread().getName();
Sy