文章目录
- 完整的线程状态转换图
- 理论层面
- 代码层面
- 线程池
- 3种线程池
- 线程池的使用
- 多线程的实现方式三:实现Callable接口
- 单例设计模式(线程安全)
完整的线程状态转换图
理论层面
代码层面
线程池
提高效率
3种线程池
Executors: 线程工具类, 负责产生线程池
ExecutorServices: 代表线程池对象,负责接受线程池
ExecutorService newCachedThreadPool()
- 特点:
- 会根据需要创建新线程,也可以自动删除,60s处于空闲状态的线程
- 线程数量可变,立刻执行提交的异步任务(异步任务:在子线程中执行的任务)
- 特点:
ExecutorService newFixedThreadPool(int nThreads)
- 特点:
- 线程数量固定
- 维护一个无界队列(暂存已提交的来不及执行的任务)
- 按照任务的提交顺序,将任务执行完毕
- 特点:
ExecutorService newSingleThreadExecutor()
- 特点:
- 单个线程
- 维护了一个无界队列(暂存已提交的来不及执行的任务)
- 按照任务的提交顺序,将任务执行完毕
- 特点:
线程池的使用
向线程池传入:
Future<?> submit(Runnable task)
Future<T> submit(Callable<T> task)
说明:
Future
表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。
eg:
public class Demo {
public static void main(String[] args) {
/*
线程池的使用:
Future<?> submit(Runnable task)
Future<T> submit(Callable<T> task)
*/
// 1. 创建线程池对象
// Executors: 线程工具类, 负责产生线程池
ExecutorService pool = Executors.newCachedThreadPool();
// 2. 向线程池中提交任务
pool.submit(new MyRunnableTask());
pool.submit(new MyRunnableTask());
}
}
class MyRunnableTask implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "hello world");
}
}
关闭线程池:
shutdown() // 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
shutdownNow() // 试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
eg:
public class Demo {
public static void main(String[] args) {
/*
线程池的使用:
Future<?> submit(Runnable task)
Future<T> submit(Callable<T> task)
*/
// 1. 创建线程池对象
// Executors: 线程工具类, 负责产生线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
// 2. 向线程池中提交任务
pool.submit(new MyRunnableTask());
pool.submit(new MyRunnableTask());
pool.submit(new MyRunnableTask());
pool.submit(new MyRunnableTask());
// 3. 关闭线程池
pool.shutdown();
pool.shutdownNow();
}
}
class MyRunnableTask implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "hello world");
}
}
向线程池中提交callable类型的任务:
Future 用来存储返回值的结果(Callable是带返回值的)
- V(表示返回值数据的类型)
get() ----> 如有必要,等待计算完成,然后获取其结果。
- 可以得到这个
get()
也是一个阻塞的方法
- 可以得到这个
eg:
public class Demo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
// submit(Callable task)
Future<String> future = pool.submit(new MyCallableTask());
// 拿到返回值结果
String s = future.get();
System.out.println(s);
}
}
class MyCallableTask implements Callable<String>{
@Override
public String call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
return "aaaa";
}
}
多线程的实现方式三:实现Callable接口
不借助线程池,需要借助FutureTask
构造方法:
FutureTask(Callable<V> callable)
// 创建一个 FutureTask,一旦运行就执行给定的 Callable。
eg:
public class Demo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1. 创建FutureTask对象
/*
FutureTask(Callable<V> callable)
创建一个 FutureTask,一旦运行就执行给定的 Callable。
*/
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
// 2. 让任务运行在线程中
Thread t = new Thread(futureTask);
t.start();
// 3. 获取任务执行的结果
String s = futureTask.get();
System.out.println(s);
}
}
class MyCallable implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("bbb");
return "aaa";
}
}
单例设计模式(线程安全)
- 构造方法私有
- 提供一个全局的自身的成员变量
- 提供一个静态的方法获取实例
同步方法:
public class Singleton {
//2. 提供一个全局的自身的成员变量
private static Singleton instance;
// 1. 构造方法私有
private Singleton() {
}
//3. 提供一个静态的方法获取实例
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
双重认证:
public class Singleton {
//2. 提供一个全局的自身的成员变量
private static Singleton instance;
// 1. 构造方法私有
private Singleton() {
}
//3. 提供一个静态的方法获取实例
public static Singleton getInstance() {
// double check
if (instance == null) {
// 假设A线程抢到了CPU执行权 A执行
// A持有锁对象
// 切换B线程 B执行
// B没有锁 进入不了sync
synchronized (Singleton.class) {
// A线程进来
// B进来了
// 第二次校验
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}