线程池
线程池
1. 线程池概念
2. 标准库线程池 (面试考点)
corePoolSize -> 核心线程数, 一个线程池创建出来, 就有这么多个核心线程, 相当于正式员工
maximumPoolSize -> 最多线程数 ( 核心线程数 + 非核心线程数 )
如果任务多了核心线程数处理不过来, 就会创建新的线程处理 (非核心线程, 数量最多 -> 最多线程数 - 核心线程数)
等任务少了, 这些新创建出的非核心线程就回收了, 但是核心线程不变
keepAliveTime -> 允许非核心线程空闲的最大时间, 超过时间了就回收
unit -> 时间单位, 秒分小时
workQueue -> 线程池中, 保存执行任务的队列
threadFactory -> 创建线程的工厂类, 就是这个类中有静态方法可以直接创建对象
总结:
3. 工厂类创建线程池和基本使用
工厂类创建线程池 + 向线程池中添加任务
查看代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Test {
public static void main(String[] args) {
// 1. 能够根据任务的数目, 自动进行线程扩容.
// 可以会创建很多个线程, 系统负担大, 不好
// ExecutorService service = Executors.newCachedThreadPool();
// 2. 固定创建10个线程的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10000; i++) {
int id = i;
// 往线程池里添加任务
service.submit(new Runnable() {
@Override
public void run() {
System.out.println("hello " + id + ", " + Thread.currentThread().getName());
}
});
}
}
}
4. 自己实现线程池
1. 固定核心线程
查看代码
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyThreadPool {
// 阻塞队列
private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);
// 初始化 创建固定线程的线程池 (FixedThreadPool)
public MyThreadPool(int n) {
for (int i = 0;i < n;i++) {
Thread t = new Thread( () -> {
try {
while (true) {
Runnable runnable = queue.take();
runnable.run();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t.start();
}
}
// 把任务添加到线程池中
public void submit(Runnable runnable) throws InterruptedException {
queue.put(runnable);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
MyThreadPool threadPool = new MyThreadPool(10);
for (int i = 0;i < 10000;i++) {
// 往线程池里添加任务
int id = i;
threadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("hello " + id + ", " + Thread.currentThread().getName());
}
});
}
}
}
2. 核心线程 + 非核心线程
查看代码
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
// 写一个比较简单的线程池.
class MyThreadPool {
private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);
private int maxPoolSize = 0;
private List<Thread> threadList = new ArrayList<>();
// 初始化线程池 (FixedThreadPool)
public MyThreadPool(int corePoolSize, int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
// 创建若干个线程
for (int i = 0; i < corePoolSize; i++) {
Thread t = new Thread(() -> {
try {
while (true) {
Runnable runnable = queue.take();
runnable.run();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start();
threadList.add(t);
}
}
// 把任务添加到线程池中
void submit(Runnable runnable) throws InterruptedException {
// 此处进行判定, 判定说当前任务队列的元素个数, 是否比较长.
// 如果队列元素比较长, 说明已有的线程, 不太能处理过来了. 创建新的线程即可.
// 如果队列不是很长, 没必要创建新的线程.
queue.put(runnable);
// 这里的 阈值 都是咱们拍脑门想的.
while (queue.size() >= 500 && threadList.size() < maxPoolSize) {
// 创建新的线程即可
Thread t = new Thread(() -> {
try {
while (true) {
Runnable task = queue.take();
task.run();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start();
threadList.add(t);
}
}
}
class Demo35 {
public static void main(String[] args) throws InterruptedException {
MyThreadPool threadPool = new MyThreadPool(10, 20);
for (int i = 0; i < 10000; i++) {
int id = i;
threadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("hello " + id + ", " + Thread.currentThread().getName());
}
});
}
}
}
5. 定时器
1. Java 库函数中定时器使用
查看代码
import java.util.Timer;
import java.util.TimerTask;
class Demo36 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello 3000");
}
}, 3000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello 2000");
}
}, 2000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello 1000");
}
}, 1000);
}
}
2. 自己实现个定时器
查看代码
package demo2;
import java.util.Comparator;
import java.util.PriorityQueue;
class MyTimerTask implements Comparator<MyTimerTask>, Comparable<MyTimerTask> {
private Runnable task;
// 绝对时间
private long time;
public MyTimerTask(Runnable task,long delay) {
this.task = task;
this.time = System.currentTimeMillis() + delay;
}
public void run() {
task.run();
}
public long getTime() {
return time;
}
@Override
public int compare(MyTimerTask o1, MyTimerTask o2) {
return (int) (o1.time - o2.time);
}
@Override
public int compareTo(MyTimerTask o) {
return (int) (this.time - o.time);
}
}
class MyTimer {
private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();
private Object locker = new Object();
public MyTimer() {
Thread t = new Thread( () -> {
try {
while (true) {
synchronized (locker) {
if (queue.size() == 0) {
locker.wait();
}
MyTimerTask top = queue.peek();
// 时间到了, 执行任务
if (System.currentTimeMillis() >= top.getTime()) {
top.run();
queue.poll();
}else {
// 时间没到 -> 等待
locker.wait(top.getTime() - System.currentTimeMillis());
}
}
}
}catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start();
}
// 往队列中添加任务
public void schedule(Runnable task,long delay) {
synchronized (locker) {
MyTimerTask myTimerTask = new MyTimerTask(task,delay);
queue.offer(myTimerTask);
locker.notify();
}
}
}
class Test {
public static void main(String[] args) {
MyTimer myTimer = new MyTimer();
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello 3000");
}
}, 3000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello 2000");
}
}, 2000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello 1000");
}
}, 1000);
System.out.println("===");
}
}