前言
最近老是听起同学说服务端的高并发,那么移动端如果出现高并发我们又如何处理呢?抱着这样的疑问我模拟了一个高并发场景
模拟场景
for (int i=0;i<100;i++){//高并发
final int finalI = i;
Thread thread =new Thread(){
@Override
public void run() {
super.run();
Log.e("jjjjjj", "runnable---->"+ finalI);
}
};
ThreadPoolManager.getInstance().execute(new FutureTask<Object>(thread,null),null);
}
Thread thread =new Thread(){
@Override
public void run() {
super.run();
Log.e("jjjjjj", "runnable---->finalIrunnable");
}
};
//延迟10S放入队列
ThreadPoolManager.getInstance().execute(new FutureTask<Object>(thread,null),(long)10000);//延时执行
上述在activity的代码 主要是循环创建101个线程并将线程交由线程管理器执行 最后的线程为延时线程 可以做一些收尾工作
自定义线程管理器
代码比较长 分析都在注解中
public class ThreadPoolManager {
//静态内部类模式的单例
private static class ThreadPoolManagerHolder{
private static final ThreadPoolManager INSTANCE=new ThreadPoolManager();
}
private ThreadPoolManager(){//初始化创造自定义线程池执行器并从阻塞队列取任务执行
//核心线程数4个,最大线程10个,空闲线程存活10s,线程任务缓冲队列4个线程量
threadPoolExecutor=new ThreadPoolExecutor(4,10,10, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(4),handler);
threadPoolExecutor.execute(runnable);
};
public static ThreadPoolManager getInstance(){
return ThreadPoolManagerHolder.INSTANCE;//静态内部类在调用此函数时才加载
}
private ThreadPoolExecutor threadPoolExecutor;//预定义线程执行器
private LinkedBlockingQueue<Future<?>> service=new LinkedBlockingQueue<>();//阻塞队列
private RejectedExecutionHandler handler=new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable runnable, ThreadPoolExecutor threadPoolExecutor) {
try {
//被拒绝后重新排队
service.put(new FutureTask<Object>(runnable,null));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
private Runnable runnable=new Runnable() {
@Override
public void run() {
while (true) { //循环从阻塞队列拿线程执行
FutureTask futureTask = null;
try {
Log.e("myThreadPook","service size "+service.size());
futureTask = (FutureTask) service.take();
Log.e("myThreadPook","池 "+threadPoolExecutor.getPoolSize());
} catch (InterruptedException e) {
e.printStackTrace();
}
if (futureTask != null) {
threadPoolExecutor.execute(futureTask);
}
}
}
};
public <T> void execute(final FutureTask<T> futureTask, Object delayed){
if(futureTask!=null){
try {
if(delayed!=null){
Timer timer=new Timer();
timer.schedule(new TimerTask(){//延迟放入队列
public void run(){
try {
service.put(futureTask);
} catch (InterruptedException e) {
e.printStackTrace();
}
}},(long)delayed);
}else {
service.put(futureTask);//直接放入队列
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
结果分析
04-11 02:49:34.480 11372-11414/com.example.mac.back E/myThreadPook: service size 100
04-11 02:49:34.480 11372-11414/com.example.mac.back E/myThreadPook: 池 1
04-11 02:49:34.485 11372-11414/com.example.mac.back E/myThreadPook: service size 99
04-11 02:49:34.485 11372-11414/com.example.mac.back E/myThreadPook: 池 2
04-11 02:49:34.506 11372-11414/com.example.mac.back E/myThreadPook: service size 98
04-11 02:49:34.506 11372-11414/com.example.mac.back E/myThreadPook: 池 3
04-11 02:49:34.509 11372-11414/com.example.mac.back E/myThreadPook: service size 97
04-11 02:49:34.509 11372-11414/com.example.mac.back E/myThreadPook: 池 4
04-11 02:49:34.509 11372-11414/com.example.mac.back E/myThreadPook: service size 96
04-11 02:49:34.509 11372-11414/com.example.mac.back E/myThreadPook: 池 4
04-11 02:49:34.510 11372-11414/com.example.mac.back E/myThreadPook: service size 95
04-11 02:49:34.510 11372-11414/com.example.mac.back E/myThreadPook: 池 4
04-11 02:49:34.510 11372-11414/com.example.mac.back E/myThreadPook: service size 94
04-11 02:49:34.510 11372-11414/com.example.mac.back E/myThreadPook: 池 4
04-11 02:49:34.510 11372-11414/com.example.mac.back E/myThreadPook: service size 93
04-11 02:49:34.510 11372-11414/com.example.mac.back E/myThreadPook: 池 4
04-11 02:49:34.533 11372-11415/com.example.mac.back E/jjjjjj: runnable---->0
04-11 02:49:34.533 11372-11415/com.example.mac.back E/jjjjjj: runnable---->3
04-11 02:49:34.533 11372-11415/com.example.mac.back E/jjjjjj: runnable---->4
04-11 02:49:34.533 11372-11415/com.example.mac.back E/jjjjjj: runnable---->5
04-11 02:49:34.533 11372-11415/com.example.mac.back E/jjjjjj: runnable---->6
04-11 02:49:34.550 11372-11414/com.example.mac.back E/myThreadPook: service size 92
04-11 02:49:34.550 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.551 11372-11417/com.example.mac.back E/jjjjjj: runnable---->1
04-11 02:49:34.551 11372-11418/com.example.mac.back E/jjjjjj: runnable---->2
04-11 02:49:34.567 11372-11414/com.example.mac.back E/myThreadPook: service size 91
04-11 02:49:34.567 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.567 11372-11414/com.example.mac.back E/myThreadPook: service size 90
04-11 02:49:34.567 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.567 11372-11414/com.example.mac.back E/myThreadPook: service size 89
04-11 02:49:34.568 11372-11415/com.example.mac.back E/jjjjjj: runnable---->9
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: service size 88
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.568 11372-11415/com.example.mac.back E/jjjjjj: runnable---->10
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: service size 87
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.568 11372-11415/com.example.mac.back E/jjjjjj: runnable---->11
04-11 02:49:34.568 11372-11415/com.example.mac.back E/jjjjjj: runnable---->12
04-11 02:49:34.568 11372-11417/com.example.mac.back E/jjjjjj: runnable---->13
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: service size 86
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: service size 85
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: service size 84
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: service size 83
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: service size 82
04-11 02:49:34.568 11372-11414/com.example.mac.back E/myThreadPook: 池 5
04-11 02:49:34.570 11372-11418/com.example.mac.back E/jjjjjj: runnable---->8
04-11 02:49:34.570 11372-11418/com.example.mac.back E/jjjjjj: runnable---->14
04-11 02:49:34.570 11372-11418/com.example.mac.back E/jjjjjj: runnable---->15
04-11 02:49:34.570 11372-11418/com.example.mac.back E/jjjjjj: runnable---->16
04-11 02:49:34.570 11372-11418/com.example.mac.back E/jjjjjj: runnable---->17
04-11 02:49:34.602 11372-11419/com.example.mac.back D/OpenGLRenderer: HWUI GL Pipeline
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: service size 81
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: 池 6
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: service size 80
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: 池 6
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: service size 79
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: 池 6
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: service size 78
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: 池 6
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: service size 77
04-11 02:49:34.607 11372-11414/com.example.mac.back E/myThreadPook: 池 6
04-11 02:49:34.608 11372-11418/com.example.mac.back E/jjjjjj: runnable---->19
04-11 02:49:34.608 11372-11418/com.example.mac.back E/jjjjjj: runnable---->20
04-11 02:49:34.608 11372-11418/com.example.mac.back E/jjjjjj: runnable---->21
04-11 02:49:34.608 11372-11418/com.example.mac.back E/jjjjjj: runnable---->22
04-11 02:49:34.621 11372-11420/com.example.mac.back E/jjjjjj: runnable---->7
04-11 02:49:34.654 11372-11414/com.example.mac.back E/myThreadPook: service size 76
....................................................................................
04-11 02:49:34.911 11372-11417/com.example.mac.back E/jjjjjj: runnable---->68
04-11 02:49:34.911 11372-11417/com.example.mac.back E/jjjjjj: runnable---->69
04-11 02:49:34.912 11372-11417/com.example.mac.back E/jjjjjj: runnable---->70
04-11 02:49:34.912 11372-11414/com.example.mac.back E/myThreadPook: service size 29
04-11 02:49:34.912 11372-11414/com.example.mac.back E/myThreadPook: 池 10
04-11 02:49:34.912 11372-11414/com.example.mac.back E/myThreadPook: service size 28
04-11 02:49:34.912 11372-11414/com.example.mac.back E/myThreadPook: 池 10
04-11 02:49:34.912 11372-11414/com.example.mac.back E/myThreadPook: service size 27
04-11 02:49:34.912 11372-11414/com.example.mac.back E/myThreadPook: 池 10
04-11 02:49:34.912 11372-11414/com.example.mac.back E/myThreadPook: service size 26
04-11 02:49:34.912 11372-11414/com.example.mac.back E/myThreadPook: 池 10
04-11 02:49:34.913 11372-11414/com.example.mac.back E/myThreadPook: service size 25
04-11 02:49:34.913 11372-11414/com.example.mac.back E/myThreadPook: 池 10
04-11 02:49:34.913 11372-11414/com.example.mac.back E/myThreadPook: service size 25
04-11 02:49:34.913 11372-11414/com.example.mac.back E/myThreadPook: 池 10
04-11 02:49:34.913 11372-11414/com.example.mac.back E/myThreadPook: service size 25
....................................................................................
04-11 02:49:34.961 11372-11414/com.example.mac.back E/myThreadPook: service size 0
04-11 02:49:34.963 11372-11417/com.example.mac.back E/jjjjjj: runnable---->82
04-11 02:49:34.964 11372-11421/com.example.mac.back E/jjjjjj: runnable---->87
04-11 02:49:34.968 11372-11426/com.example.mac.back E/jjjjjj: runnable---->67
04-11 02:49:44.495 11372-11414/com.example.mac.back E/myThreadPook: 池 10
04-11 02:49:44.501 11372-11415/com.example.mac.back E/jjjjjj: runnable---->finalIrunnable
04-11 02:49:44.501 11372-11414/com.example.mac.back E/myThreadPook: service size 0
首先在activity中将100个线程任务都加入阻塞队列中 然后线程执行器开始从阻塞队列中取任务 因为设置核心线程数为4 所以会在线程池中为任务创建新线程 直到为4 并将其他任务先加入到 线程执行器的缓冲队列中 这里我们设置了队列容量为4 已经完成了8个线程的分配
因为设置的最大线程数是10 当线程队列和缓冲队列都满时 线程池还会创建一个新线程 所以线程池中线程数量为5 并执行了5个任务 缓冲任务还剩3个任务 进入线程池运行 同时又有新线程 进入缓冲队列 这样进行 直到线程池线程和缓冲队列又满时 线程池 又会创建新线程 。。。直到线程池中线程个数为10
当线程池和缓冲队列都满时 会将阻塞队列的线程任务拒绝并重排 导致阻塞队列长度不变
最后我们可以看到阻塞队列的线程都已经执行完成 还有延迟任务也被成功执行
End.