add Thread/ThreadPool

master
Omooo 6 years ago
parent 526d0d2255
commit fb9dbb7074
  1. 12
      blogs/Java/并发/管程(Monitor).md
  2. 129
      blogs/Java/并发/线程、线程池.md

@ -1,10 +1,8 @@
--- ---
Java 并发编程 管程:并发编程的万能钥匙
--- ---
#### 目录 ##### 前言
#### 管程:并发编程的万能钥匙
管程,对应的英文是 Monitor,也称监视器。 管程,对应的英文是 Monitor,也称监视器。
@ -68,4 +66,8 @@ Java 参考了 MESA 模型,语言内置的管程(synchronized)对 MESA 模
![](https://i.loli.net/2019/03/18/5c8f0eba877b4.png) ![](https://i.loli.net/2019/03/18/5c8f0eba877b4.png)
Java 内置的管程方案(synchronized)使用简单,synchronized 关键字修饰的代码块,在编译期会自动生成相关加锁和解锁的代码,但是仅支持一个条件变量;而 Java SDK 并发包实现的管程支持多个条件变量,不过并发包里的锁,需要开发人员自己进行加锁和解锁操作。 Java 内置的管程方案(synchronized)使用简单,synchronized 关键字修饰的代码块,在编译期会自动生成相关加锁和解锁的代码,但是仅支持一个条件变量;而 Java SDK 并发包实现的管程支持多个条件变量,不过并发包里的锁,需要开发人员自己进行加锁和解锁操作。
##### 摘自:
[管程:并发编程的万能钥匙](https://time.geekbang.org/column/article/86089)

@ -0,0 +1,129 @@
---
Java 线程、线程池
---
#### 目录
1. 前言
2. 线程的创建
3. Callable 与 Future
4. 线程池
5. 参考
#### 前言
#### 线程的创建
我们知道,线程的创建有两种方式:一种是继承 Thread 类,另一种是实现 Runnable 接口。但是这两种方式有一个共同的缺陷,那就是在执行任务后无法获取执行结果(两者 run 方法的返回类型都是 void )。于是在 JDK 5 就引入了 Callable 和 Future。
#### Callable 与 Future
##### Callable
```java
public interface Callable<V> {
V call() throws Exception;
}
```
Callable 是一个泛型接口,你可以完全把它理解为一个有返回类型并且可抛异常的 Runnable。
那么是如何获取 Callable 的返回结果呢?通常是通过 FutureTask 这个中间媒介来实现的。
##### FutureTask
FutureTask 实现了 Runnable 和 Future 接口,所以我们可以直接用 Thread 来执行它,也可以使用 ExecuteService 来执行。这里就以 Thread 包装来执行:
```java
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Callable<Integer> call = () -> {
System.out.println("线程执行...");
Thread.sleep(2000);
return 1;
};
FutureTask<Integer> task = new FutureTask<>(call);
new Thread(task).start();
System.out.println(task.get());
}
}
```
##### Future
Future 的核心思想是:一个方法,计算过程可能非常耗时,等待方法返回显然不可取。可以在执行方法的时候,立马就返回一个 Future 对象,通过这个 Future 对象去控制方法的计算过程。
```java
public interface Future<V> {
/**
* 取消任务
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* 判断是否取消
*/
boolean isCancelled();
/**
* 判断是否已完成
*/
boolean isDone();
/**
* 获取任务结果,如果未完成,则等待
*/
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
```
#### 线程池
线程池是为了线程的复用,避免重复创建和销毁线程所带来的性能损耗。
##### ThreadPoolExecutor
ThreadPoolExecutor 类是线程池中最核心的一个类,它提供了四个构造方法:
```java
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue){};
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory){};
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler){};
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler){};
```
前面三个构造方法都是通过调用第四个构造方法来进行初始化工作的,下面解释一下各个参数的含义:
- corePoolSize
核心线程的大小。在创建线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了 prestartAllCoreThreads() 或者 prestartCoreThread() 方法,从这两个方法名就可以看出,是预创建线程的意思。
#### 参考
[Java并发编程:线程池的使用](https://www.cnblogs.com/dolphin0520/p/3932921.html)
Loading…
Cancel
Save