实际开发什么场景⽤到线程池_线程池的原理与使⽤场景
1、线程池简介:
多线程技术主要解决处理器单元内多个线程执⾏的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能⼒。
假设⼀个服务器完成⼀项任务所需时间为:T1 创建线程时间,T2 在线程中执⾏任务的时间,T3 销毁线程时间。
如果:T1 + T3 远⼤于 T2,则可以采⽤线程池,以提⾼服务器性能。
⼀个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):⽤于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、⼯作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执⾏任务;
3、任务接⼝(Task):每个任务必须实现的接⼝,以供⼯作线程调度任务的执⾏,它主要规定了任务的⼊⼝,任务执⾏完后的收尾⼯作,任务的执⾏状态等;
4、任务队列(taskQueue):⽤于存放没有处理的任务。提供⼀种缓冲机制。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从⽽提⾼服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者⼀些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
线程池不仅调整T1,T3产⽣的时间段,⽽且它还显著减少了创建线程的数⽬,看⼀个例⼦:
假设⼀个服务器⼀天要处理50000个请求,并且每个请求需要⼀个单独的线程完成。在线程池中,线程数⼀般是固定的,所以产⽣线程总数不会超过线程池中线程的数⽬,⽽如果服务器不利⽤线程池来处理这些请求则线程总数为50000。⼀般线程池⼤⼩是远⼩于50000。所以利⽤线程池的服务器程序不会为了创建50000⽽在处理请求时浪费时间,从⽽提⾼效率。
代码实现中并没有实现任务接⼝,⽽是把Runnable对象加⼊到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了
复制代码
复制代码
package mine.util.thread;
import java.util.LinkedList;
import java.util.List;
/**
* 线程池类,线程管理器:创建线程,执⾏任务,销毁线程,获取线程基本信息
*/
public final class ThreadPool {
// 线程池中默认线程的个数为5
private static int worker_num = 5;
// ⼯作线程
private WorkThread[] workThrads;
// 未处理的任务
private static volatile int finished_task = 0;
// 任务队列,作为⼀个缓冲,List线程不安全
private List taskQueue = new LinkedList();
private static ThreadPool threadPool;
// 创建具有默认线程个数的线程池
private ThreadPool() {
this(5);
}
// 创建线程池,worker_num为线程池中⼯作线程的个数
private ThreadPool(int worker_num) {
ThreadPool.worker_num = worker_num;
workThrads = new WorkThread[worker_num];
for (int i = 0; i < worker_num; i++) {
workThrads[i] = new WorkThread();
workThrads[i].start();// 开启线程池中的线程
}
}
// 单态模式,获得⼀个默认线程个数的线程池
public static ThreadPool getThreadPool() {
return getThreadPool(ThreadPool.worker_num);
}
// 单态模式,获得⼀个指定线程个数的线程池,worker_num(>0)为线程池中⼯作线程的个数// worker_num<=0创建默认的⼯作线程个数
public static ThreadPool getThreadPool(int worker_num1) {
if (worker_num1 <= 0)
worker_num1 = ThreadPool.worker_num;
if (threadPool == null)
threadPool = new ThreadPool(worker_num1);
return threadPool;
}
// 执⾏任务,其实只是把任务加⼊任务队列,什么时候执⾏有线程池管理器觉定
public void execute(Runnable task) {
synchronized (taskQueue) {
taskQueue.add(task);thread技术
}
}
// 批量执⾏任务,其实只是把任务加⼊任务队列,什么时候执⾏有线程池管理器觉定
public void execute(Runnable[] task) {
synchronized (taskQueue) {
for (Runnable t : task)
taskQueue.add(t);
}
}
/
/ 批量执⾏任务,其实只是把任务加⼊任务队列,什么时候执⾏有线程池管理器觉定
public void execute(List task) {
synchronized (taskQueue) {
for (Runnable t : task)
taskQueue.add(t);
}
}
// 销毁线程池,该⽅法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁public void destroy() {
while (!taskQueue.isEmpty()) {// 如果还有任务没执⾏完成,就先睡会吧
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// ⼯作线程停⽌⼯作,且置为null
for (int i = 0; i < worker_num; i++) {
workThrads[i].stopWorker();
workThrads[i] = null;
}
threadPool=null;
taskQueue.clear();// 清空任务队列
}
// 返回⼯作线程的个数
public int getWorkThreadNumber() {
return worker_num;
}
// 返回已完成任务的个数,这⾥的已完成是只出了任务队列的任务个数,可能该任务并没有实际执⾏完成public int getFinishedTasknumber() {
return finished_task;
}
// 返回任务队列的长度,即还没处理的任务个数
public int getWaitTasknumber() {
return taskQueue.size();
}
// 覆盖toString⽅法,返回线程池信息:⼯作线程个数和已完成任务个数
@Override
public String toString() {
return "WorkThread number:" + worker_num + " finished task number:"
+ finished_task + " wait task number:" + getWaitTasknumber();
}
/**
* 内部类,⼯作线程
*/
private class WorkThread extends Thread {
// 该⼯作线程是否有效,⽤于结束该⼯作线程
private boolean isRunning = true;
/*
* 关键所在啊,如果任务队列不空,则取出任务执⾏,若任务队列空,则等待
*/
@Override
public void run() {
Runnable r = null;
while (isRunning) {// 注意,若线程⽆效则⾃然结束run⽅法,该线程就没⽤了
synchronized (taskQueue) {
while (isRunning && taskQueue.isEmpty()) {// 队列为空
try {
taskQueue.wait(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (!taskQueue.isEmpty())
r = ve(0);// 取出任务
}
if (r != null) {
r.run();// 执⾏任务
}
finished_task++;
r = null;
}
}
// 停⽌⼯作,让该线程⾃然执⾏完run⽅法,⾃然结束
public void stopWorker() {
isRunning = false;
}
}
}
复制代码
复制代码
复制代码
复制代码
package mine.util.thread;
//测试线程池
public class TestThreadPool {
public static void main(String[] args) {
// 创建3个线程的线程池
ThreadPool t = ThreadPool(3);
t.destroy();// 所有线程都执⾏完成才destory

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。