ThreadFactory使用的必要性
1.阿里编码规约扫描插件的友善提醒
当我们构建一个线程池时,如果使用了阿里的编码规范扫描插件的话,会提醒我们要使用带ThreadFactory参数的ThreadPoolExecutor构造方法,Ctrl+F1进去我们会看到:
之前的文章已经介绍了线程池中ThreadFactory用于设置创建线程工厂,通过线程工厂给每个创建出来的线程设置更有意义的名字,这样就如插件提示的那样 出错时方便问题的回溯 ,所有当我们在创建线程池的时候使用带有ThreadFactory参数的构造方法是非常有必要的。
2.ThreadFactory的使用
关于ThreadFactory我们可以guava提供的ThreadFactoryBuilder,也可以自定义。这里两种方式各举一个例子:
package cc.mynatapp.detroitdentist.current;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.*;
/**
* @author Xu hao
* @Description ThreadFactory的使用
* @Version 1.0
* Email 15229357319@sina.cn
* create on 2019/4/15
*/
public class UseThreadFactory {
private static ThreadFactory namedFactory = new ThreadFactoryBuilder().setNameFormat("线程-demo-%d").build();
private static ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS, new
ArrayBlockingQueue<>(10), namedFactory, new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
for (int i = 1; i <= 14; i++) {
Callable<Boolean> task = createTask(i);
pool.submit(task);
System.out.println("after task:" + i + " submitted, current active count: "
+ pool.getActiveCount() + ", size of queue: " + pool.getQueue().size());
}
pool.shutdown();
}
/**
* @Author Xu hao
* @Description 创建任务
* @Date 2019/3/19 0:08
* @param i
* @return java.util.concurrent.Callable<java.lang.Boolean>
**/
private static Callable<Boolean> createTask(int i){
Callable<Boolean> callable = () -> {
TimeUnit.SECONDS.sleep(10);
System.out.println("thread: " + Thread.currentThread().getName() + " execute task: " + i);
return true;
};
return callable;
}
}
当然,我们也可以自定义ThreadFactory,举例如下:
package cc.mynatapp.detroitdentist.current;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author Xu hao
* @Description ThreadFactory的使用
* @Version 1.0
* Email 15229357319@sina.cn
* create on 2019/4/15
*/
public class UseThreadFactory {
/**
* 自定义ThreadFactory
**/
private static ThreadFactory namedFactory = nameThreadFactory();
private static ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS, new
ArrayBlockingQueue<>(10), namedFactory, new ThreadPoolExecutor.AbortPolicy());
public static void main(String[] args) {
for (int i = 1; i <= 14; i++) {
Callable<Boolean> task = createTask(i);
pool.submit(task);
System.out.println("after task:" + i + " submitted, current active count: "
+ pool.getActiveCount() + ", size of queue: " + pool.getQueue().size());
}
pool.shutdown();
}
/**
* @Author Xu hao
* @Description 创建任务
* @Date 2019/3/19 0:08
* @param i
* @return java.util.concurrent.Callable<java.lang.Boolean>
**/
private static Callable<Boolean> createTask(int i){
Callable<Boolean> callable = () -> {
TimeUnit.SECONDS.sleep(10);
System.out.println("thread: " + Thread.currentThread().getName() + " execute task: " + i);
return true;
};
return callable;
}
/**
* @Author Xu hao
* @Description 自定义ThreadFactory
* @Date 2019/4/19 23:28
* @param
* @return java.util.concurrent.ThreadFactory
**/
private static ThreadFactory nameThreadFactory(){
AtomicInteger tag = new AtomicInteger(1);
ThreadFactory factory = (Runnable r) -> {
Thread thread = new Thread(r);
thread.setName("线程-demo-" + tag.getAndIncrement());
return thread;
};
return factory;
}
}
运行上面两种方法的举例都可以得到如下日志输出,我们可以看到线程池中的线程被命名为“线程-demo-%d”了