- 线程池:什么是线程池?
线程池是指在初始化一个多线程应用程序过程中创建一个线程集合,然后在需要执行新的任务时重用这些线程而不是新建一个线程(提高线程复用,减少性能开销)。线程池中线程的数量通常完全取决于可用内存数量和应用程序的需求。然而,增加可用线程数量是可能的。线程池中的每个线程都有被分配一个任务,一旦任务已经完成了,线程回到池子中然后等待下一次分配任务。 - 为什么要使用线程池?
- 线程池改进了一个应用程序的响应时间。由于线程池中的线程已经准备好且等待被分配任务,应用程序可以直接拿来使用而不用新建一个线程。
- 线程池节省了CLR 为每个短生存周期任务创建一个完整的线程的开销并可以在任务完成后回收资源。
- 线程池根据当前在系统中运行的进程来优化线程时间片。
- 线程池允许我们开启多个任务而不用为每个线程设置属性。
- 线程池允许我们为正在执行的任务的程序参数传递一个包含状态信息的对象引用。
- 线程池可以用来解决处理一个特定请求最大线程数量限制问题。
- 线程池流程分析
- 首先线程池判断基本线程池是否已满?没满,创建一个工作线程来执行任务。满了,则进入下个流程。
- 其次线程池判断工作队列是否已满?没满,则将新提交的任务存储在工作队列里。满了,则进入下个流程。
- 最后线程池判断整个线程池是否已满?没满,则创建一个新的工作线程来执行任务,满了,则交给饱和策略来处理这个任务。
- 代码:
- 带有返回值的多线程例子。
单例线程池
package xiancheng;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* @Author: kevin
* @Date: 2019-04-11 13:15
*/
public class ThreadPool {
/**
* // 构造一个任务池
* 参数说明:
* corePoolSize - 池中所保存的线程数,包括空闲线程。
* maximumPoolSize - 池中允许的最大线程数。
* keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
* unit - keepAliveTime 参数的时间单位。
* workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
* threadFactory - 执行程序创建新线程时使用的工厂。
* handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序
*/
private ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5));
private static ThreadPool instance = null;
private ThreadPool(){
}
/**
* 使用线程执行任务
* @param runnable
*/
public void executor(Runnable runnable) {
executor.execute(runnable);
}
/**
* 关闭线程池
*/
public void shutdown() {
executor.shutdown();
}
/**
* 获取单例的线程池对象:双锁检查实现单例线程池
* @return
*/
public static ThreadPool getThreadPool() {
if (instance == null) {
synchronized (ThreadPool.class) {
if (instance == null) {
instance = new ThreadPool();
}
}
}
return instance;
}
}
处理任务Integer
package xiancheng.test;
import org.apache.commons.compress.utils.Lists;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* @Author: kevin
* @Date: 2019-04-12 09:57
*/
public class GetThreadInteger implements Runnable {
AtomicReference<List<Integer>> resultInteger = new AtomicReference<>();
@Override
public void run() {
resultInteger.set(getIntegers());
}
public static List<Integer> getIntegers() {
List<Integer> list = Lists.newArrayList();
for (int i = 100; i < 200; i++) {
System.out.println(Thread.currentThread().getName() + "=====" + i);
list.add(i);
}
return list;
}
}
String
package xiancheng.test;
import org.apache.commons.compress.utils.Lists;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
/**
* @Author: kevin
* @Date: 2019-04-12 09:57
*/
public class GetThreadString implements Runnable {
AtomicReference<List<String>> resultString = new AtomicReference<>();
@Override
public void run() {
resultString.set(getStrings());
}
public List<String> getStrings() {
List<String> list = Lists.newArrayList();
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "=====" + i);
list.add(String.valueOf(i));
}
return list;
}
}
测试类:
package xiancheng.test;
import xiancheng.ThreadPool;
import java.util.List;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicReference;
/**
* @Author: kevin
* @Date: 2019-04-12 09:31
*/
public class TestThread {
public static void main(String[] args) {
AtomicReference<List<String>> resultString = new AtomicReference<>();
AtomicReference<List<Integer>> resultInteger = new AtomicReference<>();
ThreadPool threadPool = ThreadPool.getThreadPool();
try {
/**
* 无返回值的多线程
*/
threadPool.executor(new GetThreadString());
threadPool.executor(new GetThreadInteger());
for (int i = 0; i < 100; i++) {
System.out.println("========--------" + Thread.currentThread().getName());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();
}
System.out.println(resultInteger.get().size());
System.out.println(resultString.get().size());
}
}
处理任务String:
package xiancheng.test;
import org.apache.commons.compress.utils.Lists;
import java.util.List;
import java.util.concurrent.Callable;
/**
* @Author: kevin
* @Date: 2019-04-12 13:20
*/
public class GetThreadStringReturn implements Callable<List<String>> {
@Override
public List<String> call() throws Exception {
List<String> list = Lists.newArrayList();
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "=====" + i);
list.add(String.valueOf(i));
}
return list;
}
}
Integer:
package xiancheng.test;
import org.apache.commons.compress.utils.Lists;
import java.util.List;
import java.util.concurrent.Callable;
/**
* @Author: kevin
* @Date: 2019-04-12 13:20
*/
public class GetThreadIntegerReturn implements Callable<List<Integer>> {
@Override
public List<Integer> call() throws Exception {
List<Integer> list = Lists.newArrayList();
for (int i = 100; i < 200; i++) {
System.out.println(Thread.currentThread().getName() + "=====" + i);
list.add(i);
}
return list;
}
}
测试类:
package xiancheng.test;
import xiancheng.ThreadPool;
import java.util.List;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicReference;
/**
* @Author: kevin
* @Date: 2019-04-12 09:31
*/
public class TestThread {
public static void main(String[] args) {
AtomicReference<List<String>> resultString = new AtomicReference<>();
AtomicReference<List<Integer>> resultInteger = new AtomicReference<>();
ThreadPool threadPool = ThreadPool.getThreadPool();
try {
/**
* 有返回值的多线程
*/
FutureTask<List<String>> listStringFutureTask = new FutureTask(new GetThreadStringReturn());
FutureTask<List<Integer>> listIntegerFutureTask = new FutureTask(new GetThreadIntegerReturn());
threadPool.executor(listStringFutureTask);
threadPool.executor(listIntegerFutureTask);
resultString.set(listStringFutureTask.get());
resultInteger.set(listIntegerFutureTask.get());
for (int i = 0; i < 100; i++) {
System.out.println("========--------" + Thread.currentThread().getName());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
threadPool.shutdown();
}
System.out.println(resultInteger.get().size());
System.out.println(resultString.get().size());
}
}
- 线程池的监控
taskCount:线程池需要执行的任务数量。
completedTaskCount:线程池在运行过程中已完成的任务数量。小于或等于taskCount。
largestPoolSize:线程池曾经创建过的最大线程数量。通过这个数据可以知道线程池是否满过。如等于线程池的最大大小,则表示线程池曾经满了。
getPoolSize:线程池的线程数量。如果线程池不销毁的话,池里的线程不会自动销毁,所以这个大小只增不减。
getActiveCount:获取活动的线程数。
菜鸟一个,如有不对,欢迎指出。。。。