为什么要使用线程池:
如果频繁的创建线程的情况下,非常的消耗cpu资源,重复放从就绪到运行状态调度,效率非常低。
所以采用线程池直接实现反复复用,创建好一个线程后,不会立马销毁掉,而是一直复用。从而直接从运行状态调度,可以提高效率。
为什么使用线程池可以提高效率:无需cpu调度切换,直接运行。
线程池的优缺点:
1,效率比较高
2,统一管理我们的线程
3,提高线程复用。
缺点:
非常消耗cpu资源:
线程池里面: 核心线程数,最大线程数。超时时间
线程池的作用
1.降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。
2.提高响应速度:任务到达时,无需等待线程创建即可立即执行。
3.提高线程的可管理性:线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。
4.提供更多更强大的功能:线程池具备可拓展性,允许开发人员向其中增加更多的功能。比如延时定时线程池ScheduledThreadPoolExecutor,就允许任务延期执行或定期执行
线程池的创建方式:
Executors.newCachedThreadPool(); 可缓存线程池
Executors.newFixedThreadPool();可定长度
Executors.newScheduledThreadPool() ; 可定时
Executors.newSingleThreadExecutor(); 单例
底层都是基于ThreadPoolExecutor构造函数封装
简单手写线程池:
可定长线程池:
package com.taotao.metithread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*@author tom
*Date 2020/7/29 0029 8:03
*创建线程池
*/
public class Test040 {
public static void main(String[] args) {
//底层只会创建2个线程复用
//可以定长线程池
ExecutorService executorService= Executors.newFixedThreadPool(2);
for (int i = 0; i <10 ; i++) {
int fini=i;
executorService.execute(()->
System.out.println(Thread.currentThread().getName()+":"+fini));
}
}
}
public static ExecutorService newCachedThreadPool() {
//核心线程数,最大线程数,单位(分、秒),队列
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
1,newFixedThreadPool 采用的是无界队列 LinkedBlockingQueue
阻塞队列
1.ArrayBlockingQueue:
有界队列,基于数组结构,按照队列FIFO原则对元素排序;
2.LinkedBlockingQueue:
无界队列,基于链表结构,按照队列FIFO原则对元素排序,Executors.newFixedThreadPool()使用了这个队列; 无界默认是Integer.MAX_VALUE,有界则是 可以自己定义
3.SynchronousQueue:
同步队列,该队列不存储元素,每个插入操作必须等待另一个线程调用移除操作,否则插入操作会一直被阻塞,Executors.newCachedThreadPool()使用了这个队列;
4.PriorityBlockingQueue:
优先级队列,具有优先级的无限阻塞队列。
有界无界的区分: 是否设置初始值。
LinkedBlockingDeque
package com.taotao.metithread;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
/**
*@author tom
*Date 2020/7/29 0029 8:38
*阻塞与非阻塞
*/
public class Test042 {
public static void main(String[] args) throws InterruptedException {
LinkedBlockingDeque<String> strings=new LinkedBlockingDeque<>(3);
strings.offer("mayikt");
strings.offer("meite");
strings.offer("wwss");
strings.offer("23");
boolean xiaowie=strings.offer("xiaowie",3,TimeUnit.SECONDS);
System.out.println(xiaowie);
// System.out.println(strings.peek());
// System.out.println(strings.peek());
// System.out.println(strings.peek());
// System.out.println(strings.peek());
System.out.println(strings.poll());
System.out.println(strings.poll());
System.out.println(strings.poll());
System.out.println(strings.poll(3, TimeUnit.SECONDS));
//poll取出成功的话会将元素从队列删除
//peek 获取元素不删除
}
}
image.png
package com.taotao.metithread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
/**
*@author tom
*Date 2020/7/29 0029 9:21
*手写线程池
*/
public class MayijtExecutor {
//存放我们提交任务的线程
private BlockingQueue<Runnable> runnables;
//一直运行的线程,核心线程:
private List<TaskThread> taskThreads;
public MayijtExecutor(int codeThreads, int queueSize) {
taskThreads = new ArrayList<TaskThread>();
runnables = new LinkedBlockingDeque(queueSize);
for (int i = 0; i < codeThreads; i++) {
TaskThread taskThread = new TaskThread();
taskThread.start();
taskThreads.add(taskThread);
}
}
class TaskThread extends Thread {
@Override
public void run() {
//停掉线程池
while (runnables.size() > 0 || true) {
Runnable runnable = runnables.poll();
if (runnable != null) {
runnable.run();
}
}
}
}
public boolean executor(Runnable runnable) throws InterruptedException {
runnables.offer(runnable, 2, TimeUnit.SECONDS);
return false;
}
public static void main(String[] args) throws InterruptedException {
MayijtExecutor myExecutor = new MayijtExecutor(2, 2);
for (int i = 0; i < 10; i++) {
int finalI = i;
boolean executor = myExecutor.executor(() -> {
System.out.println(Thread.currentThread().getName() + "," + finalI);
});
}
}
}
网友评论