前言:
我们在实际项目开发中,当项目上线后每次发一个请求我们后台就创建一个新线程,首先我们大家应该知道,java是运行在jvm上面的,如果创建的线程特别的多,线程的创建和销毁就需要jvm频繁的进行处理,同时如果我们的发的请求的时间特别短,处理数据很快,但是jvm再处理线程的时间特别长,这就会造成性能上的瓶颈,所以引出我们的线程池工厂类,他是一个接口,同时也是一个规范。下面介绍其各个实现类:
demo练习:
newCachedThreadPool()方法创建无界线程池
无界线程池,大白话就是创建的线程池,存放无穷的线程个数,理论上的Integer.MAX_VALUE的最大值。
实现对象复用效果:
package com.zcw.demo;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @ClassName : MyRunnable
* @Description : MyRunnable
* @Author : Zhaocunwei
* @Date: 2020-04-21 10:45
*/
@Slf4j
public class MyRunnable implements Runnable {
private String userName;
public MyRunnable(String userName){
super();
this.userName =userName;
}
@Override
public void run(){
log.info(Thread.currentThread().getName()+"userName="+userName+"begin"+System.currentTimeMillis());
log.info(Thread.currentThread().getName()+"userName="+userName+"end"+System.currentTimeMillis());
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
for(int i=0;i<5;i++){
executorService.execute(new MyRunnable((" "+(i+1))));
}
Thread.sleep(1000);
log.info("===================");
log.info("===================");
for(int i=0;i<5;i++){
executorService.execute(new MyRunnable((""+(i+1))));
}
}
}
运行结果:
贴心服务–可以进行定制线程工厂
我们这里可以使用自定义的ThreadFactory接口实现类,实现线程对象的贴心定制
package com.zcw.demo;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
/**
* @ClassName : MyThreadFactory
* @Description : 自定义线程工厂类
* @Author : Zhaocunwei
* @Date: 2020-04-21 11:01
*/
@Slf4j
public class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable runnable){
Thread thread = new Thread(runnable);
thread.setName("贴心服务--定制线程池中的线程对象的名称"+Math.random());
return thread;
}
public static void main(String[] args) {
MyThreadFactory myThreadFactory = new MyThreadFactory();
ExecutorService executorService = Executors.newCachedThreadPool(myThreadFactory);
executorService.execute(new Runnable() {
@Override
public void run() {
log.info("进行中"+System.currentTimeMillis()+" "+Thread.currentThread().getName());
}
});
}
}
运行结果:
11:05:12.582 [贴心服务--定制线程池中的线程对象的名称0.6235705390619012] INFO com.zcw.demo.MyThreadFactory - 进行中1587438312580 贴心服务--定制线程池中的线程对象的名称0.6235705390619012
现在进行有界线程展示:
顾名思义就是我们创建线程池个数可以指定最大的数量:
newFixedThreadPool(int)
package com.zcw.demo;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @ClassName : MyRunnable
* @Description : 创建有界线程池
* @Author : Zhaocunwei
* @Date: 2020-04-21 11:20
*/
@Slf4j
public class MyRunnable implements Runnable {
private String userName;
public MyRunnable(String userName){
super();
this.userName =userName;
}
@Override
public void run(){
log.info(Thread.currentThread().getName()+"userName="+userName+"begin="+System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info(Thread.currentThread().getName()+"userName="+userName+"end"+System.currentTimeMillis());
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
for(int i=0;i<3;i++){
executorService.execute(new MyRunnable((""+(i+1))));
}
for(int i=0;i<3;i++){
executorService.execute(new MyRunnable((""+(i+1))));
}
}
}
展示效果:
最骚的操作:贴心定制定长线程池,私有专属线程池(自己定制)
package com.zcw.demo;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
/**
* @ClassName : MyThreadFactory
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-04-21 11:37
*/
@Slf4j
public class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName("就是这么酸爽,自己定制对象的名称"+Math.random());
return thread;
}
public static void main(String[] args) {
MyThreadFactory myThreadFactory = new MyThreadFactory();
ExecutorService excutorService = Executors.newFixedThreadPool(2,myThreadFactory);
Runnable runnable = new Runnable() {
@Override
public void run() {
log.info("begin ,,, 进行中..."+System.currentTimeMillis()+" "+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("end 运行..."+System.currentTimeMillis()+""+Thread.currentThread().getName());
}
};
excutorService.execute(runnable);
excutorService.execute(runnable);
excutorService.execute(runnable);
}
}
运行结果:
11:42:41.677 [就是这么酸爽,自己定制对象的名称0.8462610517260408] INFO com.zcw.demo.MyThreadFactory - begin ,,, 进行中...1587440561674 就是这么酸爽,自己定制对象的名称0.8462610517260408
11:42:41.677 [就是这么酸爽,自己定制对象的名称0.9806786749850551] INFO com.zcw.demo.MyThreadFactory - begin ,,, 进行中...1587440561674 就是这么酸爽,自己定制对象的名称0.9806786749850551
11:42:44.681 [就是这么酸爽,自己定制对象的名称0.9806786749850551] INFO com.zcw.demo.MyThreadFactory - end 运行...1587440564681就是这么酸爽,自己定制对象的名称0.9806786749850551
11:42:44.681 [就是这么酸爽,自己定制对象的名称0.8462610517260408] INFO com.zcw.demo.MyThreadFactory - end 运行...1587440564681就是这么酸爽,自己定制对象的名称0.8462610517260408
11:42:44.681 [就是这么酸爽,自己定制对象的名称0.9806786749850551] INFO com.zcw.demo.MyThreadFactory - begin ,,, 进行中...1587440564681 就是这么酸爽,自己定制对象的名称0.9806786749850551
11:42:47.682 [就是这么酸爽,自己定制对象的名称0.9806786749850551] INFO com.zcw.demo.MyThreadFactory - end 运行...1587440567682就是这么酸爽,自己定制对象的名称0.9806786749850551
创建单一线程池模拟MQ,我行我素
package com.zcw.demo;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @ClassName : MyRunnable
* @Description :
* @Author : Zhaocunwei
* @Date: 2020-04-21 11:44
*/
@Slf4j
public class MyRunnable implements Runnable {
private String userName;
public MyRunnable(String userName){
super();
this.userName =userName;
}
@Override
public void run() {
log.info(Thread.currentThread().getName()+"username="+userName+"begin"+System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info(Thread.currentThread().getName()+"username="+userName+"end"+System.currentTimeMillis());
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for(int i=0;i<3;i++){
executorService.execute(new MyRunnable(""+(i+1)));
}
}
}
运行结果: