package com.yuxue.juc.threadPool;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* 多线程中,第三种获得多线程的方式
* */
public class CallableTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//FutureTask(Callable callable)
FutureTask futureTask = new FutureTask<>(new myThread());
new Thread(futureTask, "AAA").start();
//new Thread(futureTask, "BBB").start();//复用,直接取值,不要重启两个线程
int a = 100;
int b = 0;
//b = futureTask.get();//要求获得Callable线程的计算结果,如果没有计算完成就要去强求,会导致堵塞,直到计算完成
while (!futureTask.isDone()) {
当futureTask完成后取值
b = futureTask.get();
}
System.out.println("===Result is:" + (a + b));
}
}
class myThread implements Callable {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + "\tget in the callable");
Thread.sleep(5000);
return 1024;
}
}
两者区别:
核心执行代码为:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
那么我们再点进this方法可以看到其全参数的构造方法为:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
简单介绍一下:
如上图所属,其流程为:
回答:一个都不用,我们生产上只能使用自定义的!!!!
为什么?
线程池不允许使用Executors创建,试试通过ThreadPoolExecutor的方式,规避资源耗尽风险
阿里巴巴规范手册当中提到:
上代码:
package com.yuxue.juc.threadPool;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MyThreadPoolDemo {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
//corePoolSize:常驻核心线程数
2,
//maximumPoolSize:最大的可容纳线程数
5,
//存活时间设置为1s
1L,
TimeUnit.SECONDS,
//这里用LinkedBlockingQueue,且容量为3,意味着等候区最大容量三个任务
new LinkedBlockingQueue<>(3),
//默认的defaultThreadFactory即可
Executors.defaultThreadFactory(),
//丢弃方法使用AbortPolicy()
new ThreadPoolExecutor.AbortPolicy());
//这里用来做任务的处理执行
for (int i = 0; i < 5; i++) {
threadPoolExecutor.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t 办理业务;");
});
}
threadPoolExecutor.shutdown();
}
}
我们运行结果为:
pool-1-thread-2 办理业务;
pool-1-thread-1 办理业务;
pool-1-thread-2 办理业务;
pool-1-thread-1 办理业务;
pool-1-thread-2 办理业务;
//可以看到当我们任务书为5且处理速度非常快时,我们就用核心的corePoolSize就可以满足任务需求
当任务数量变多或者任务变重时:如将我们的任务数量调整为20时,此时运行结果为:
pool-1-thread-1 办理业务;
pool-1-thread-3 办理业务;
pool-1-thread-2 办理业务;
pool-1-thread-3 办理业务;
pool-1-thread-1 办理业务;
pool-1-thread-4 办理业务;
pool-1-thread-1 办理业务;
pool-1-thread-3 办理业务;
pool-1-thread-2 办理业务;
pool-1-thread-5 办理业务;
pool-1-thread-4 办理业务;
pool-1-thread-1 办理业务;
pool-1-thread-3 办理业务;
pool-1-thread-1 办理业务;
pool-1-thread-2 办理业务;
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.yuxue.juc.threadPool.MyThreadPoolDemo$$Lambda$1/558638686@6d03e736 rejected from java.util.concurrent.ThreadPoolExecutor@568db2f2[Running, pool size = 5, active threads = 0, queued tasks = 0, completed tasks = 15]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at com.yuxue.juc.threadPool.MyThreadPoolDemo.main(MyThreadPoolDemo.java:27)
发生了异常,且任务只执行完了15个,我们可以看到其中active threads = 0, queued tasks = 0也就是说我的阻塞队列已经满了,且没有空闲的线程了,此时再申请任务我就会抛出异常,这是线程池handler参数的拒绝策略,当我们更改策略为ThreadPoolExecutor.CallerRunsPolicy()时,运行结果当中存在main 办理业务;语句,也就意味着线程池将某些任务回退到了调用者,另外的两个拒绝策略在此就不演示
例如八核CPU:,利用公式,约为:8/(1-0,9)=80个线程