91名师指路-头部
91名师指路

手写线程池(六)

由于某些原因,现在不支持支付宝支付,如需要购买源码请加博主微信进行购买,微信号:13248254750

题外话:

在面试的时候,如果面试官问你:你在工作中单一的/固定数的/可变你的三种创建线程池的方法,你用哪个多?

答:一个都不用,我们都是自己手写的。因为阿里巴巴开发手册里面明确的提到: 线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式。


一:手写一个线程池采用AbortPolicy拒绝策略的代码如下:

package com.mszl.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
* 功能:手写一个线程池
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class ThreadPoolDiyDemo {

public static void main(String[] args) {
// int corePoolSize:2
// int maximumPoolSize:5
// long keepAliveTime, 1
// TimeUnit unit,
// BlockingQueue<Runnable> workQueue:3
// ThreadFactory threadFactory,
// RejectedExecutionHandler handler
ExecutorService threadPool=new ThreadPoolExecutor(2, 5,
1, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());

// 模拟10个用户到银行的5个窗口去取钱
try{
for(int i=1; i<=7; i++){
threadPool.execute(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + "\t" + "办理完成");
}
});
}
} catch(Exception ex){
ex.printStackTrace();
} finally{
threadPool.shutdown(); // 关闭线程池
}
}


}

当模拟7个用户取钱时执行结果为:

pool-1-thread-1	办理完成
pool-1-thread-1 办理完成
pool-1-thread-1 办理完成
pool-1-thread-1 办理完成
pool-1-thread-2 办理完成
pool-1-thread-3 办理完成
pool-1-thread-4 办理完成

当模拟9个用户取钱时执行结果为:

pool-1-thread-1	办理完成
pool-1-thread-3 办理完成
pool-1-thread-2 办理完成
pool-1-thread-1 办理完成
pool-1-thread-5 办理完成
pool-1-thread-3 办理完成
pool-1-thread-4 办理完成
pool-1-thread-1 办理完成
java.util.concurrent.RejectedExecutionException: Task com.mszl.thread.ThreadPoolDiyDemo$1@1f96302 rejected from java.util.concurrent.ThreadPoolExecutor@14eac69[Running, pool size = 5, active threads = 0, queued tasks = 0, completed tasks = 8]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
at com.mszl.thread.ThreadPoolDiyDemo.main(ThreadPoolDiyDemo.java:37)

分析:因为我们模拟的是9个用户大于了8个(最大线程数5+队列数3=8),并且我们采用的是默认的AbortPolicy拒绝策略,根据AbortPolicy的特性,直接抛异常。


二:手写一个线程池采用 CallerRunPolicy拒绝策略的代码如下:

package com.mszl.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
* 功能:手写一个线程池
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class ThreadPoolDiyDemo {

public static void main(String[] args) {
// int corePoolSize:2
// int maximumPoolSize:5
// long keepAliveTime, 1
// TimeUnit unit,
// BlockingQueue<Runnable> workQueue:3
// ThreadFactory threadFactory,
// RejectedExecutionHandler handler
ExecutorService threadPool=new ThreadPoolExecutor(2, 5,
1, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());

// 模拟10个用户到银行的5个窗口去取钱
try{
for(int i=1; i<=9; i++){
threadPool.execute(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + "\t" + "办理完成");
}
});
}
} catch(Exception ex){
ex.printStackTrace();
} finally{
threadPool.shutdown(); // 关闭线程池
}
}


}

执行结果:

pool-1-thread-2	办理完成
pool-1-thread-4 办理完成
pool-1-thread-2 办理完成
pool-1-thread-3 办理完成
pool-1-thread-1 办理完成
pool-1-thread-5 办理完成
pool-1-thread-2 办理完成
pool-1-thread-4 办理完成
main 办理完成

分析:我们模拟的是9个用户大于了8个(最大线程数5+队列数3=8),并且我们采用的是CallerRunPolicy 拒绝策略,根据CallerRunPolicy 的特性,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。所以有一个线程退回到了main线程。


三:手写一个线程池采用 DiscardOldestPolicy 拒绝策略的代码如下:
package com.mszl.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
* 功能:手写一个线程池
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class ThreadPoolDiyDemo {

public static void main(String[] args) {
// int corePoolSize:2
// int maximumPoolSize:5
// long keepAliveTime, 1
// TimeUnit unit,
// BlockingQueue<Runnable> workQueue:3
// ThreadFactory threadFactory,
// RejectedExecutionHandler handler
ExecutorService threadPool=new ThreadPoolExecutor(2, 5,
1, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardOldestPolicy());

// 模拟10个用户到银行的5个窗口去取钱
try{
for(int i=1; i<=9; i++){
threadPool.execute(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + "\t" + "办理完成");
}
});
}
} catch(Exception ex){
ex.printStackTrace();
} finally{
threadPool.shutdown(); // 关闭线程池
}
}


}

执行结果:

pool-1-thread-2 办理完成
pool-1-thread-1 办理完成
pool-1-thread-2 办理完成
pool-1-thread-3 办理完成
pool-1-thread-4 办理完成
pool-1-thread-2 办理完成
pool-1-thread-1 办理完成
pool-1-thread-5 办理完成

分析:我们模拟的是9个用户大于了8个(最大线程数5+队列数3=8),并且我们采用的是 DiscardOldestPolicy 拒绝策略,根据 DiscardOldestPolicy 的特性,抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务。所以只有8个办理完成,还有一个被抛弃了。


四:手写一个线程池采用 DiscardPolicy 拒绝策略的代码如下:

package com.mszl.thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
* 功能:手写一个线程池
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
public class ThreadPoolDiyDemo {

public static void main(String[] args) {
// int corePoolSize:2
// int maximumPoolSize:5
// long keepAliveTime, 1
// TimeUnit unit,
// BlockingQueue<Runnable> workQueue:3
// ThreadFactory threadFactory,
// RejectedExecutionHandler handler
ExecutorService threadPool=new ThreadPoolExecutor(2, 5,
1, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardPolicy());

// 模拟10个用户到银行的5个窗口去取钱
try{
for(int i=1; i<=9; i++){
threadPool.execute(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + "\t" + "办理完成");
}
});
}
} catch(Exception ex){
ex.printStackTrace();
} finally{
threadPool.shutdown(); // 关闭线程池
}
}


}

执行结果:

pool-1-thread-2	办理完成
pool-1-thread-2 办理完成
pool-1-thread-5 办理完成
pool-1-thread-4 办理完成
pool-1-thread-3 办理完成
pool-1-thread-1 办理完成
pool-1-thread-5 办理完成
pool-1-thread-2 办理完成

分析:我们模拟的是9个用户大于了8个(最大线程数5+队列数3=8),并且我们采用的是  DiscardPolicy 拒绝策略,根据  DiscardPolicy 的特性,直接丢弃任务,不予任何处理也不抛出异常。


2019-12-03 18:11:40     阅读(1015)

名师出品,必属精品    https://www.91mszl.com

联系博主    
用户登录遮罩层
x

账号登录

91名师指路-底部