本文承接java线程池原理剖析继续讲解 ThreadPoolExecutor中的线程工厂。
线程池中的ThreadFactory作用更像是本文封面图片一样,通过线程工厂得到的线程有统一的线程上下文状态,统一的线程Prefix,统一的线程其他配置等;
线程工厂作用就是为了生成Thread,其中核心方法如下:
publicinterfaceThreadFactory {
Thread newThread(Runnable r);
}
举一个常见的线程工厂
如下是Executors类里面的默认线程工厂,可以看出来这个默认的线程工厂目的就是为了指定ThreadGroup和线程name的前缀。
static class DefaultThreadFactory implements ThreadFactory{
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
下面我们详细展开介绍如下三个概念
ThreadGroup
SecurityManager
ThreadFactory
ThreadGorup
ThreadGroup介绍
每一个java线程一定会归属于某一个线程组(ThreadGroup),线程组可以管理一组线程在,这样方便通过使用线程组来管理维护一组线程而不用一个个的去管理线程。 比如:你可以start或者suspend所有线程通过一个ThreadGroup。
一个线程一定回归属与一个线程组,你可以显示的在Thread构造方法中指定ThreadGroup,也可以不显示指定,但这个时候会放入默认线程组
线程一旦创建了, 不可以更改线程的线程组
你可以通过操作线程组的interrupt等操作集体操作一组thread的状态
public static void main(String[] args) throws InterruptedException{
ThreadGroup threadGroup = new ThreadGroup("moheqionglin");
Thread t1 = new MyThread(threadGroup, "-> ");
Thread t2 = new MyThread(threadGroup, "->| ");
Thread t3 = new MyThread();
t1.start();
t2.start();
t3.start();
System.out.println("t1 Thread group is " + t1.getThreadGroup());
System.out.println("t2 Thread group is " + t2.getThreadGroup());
System.out.println("t3 Thread group is " + t3.getThreadGroup());
for (ThreadGroup t = threadGroup; t != null; t = t.getParent()){
System.out.print(t.getName() + ", active count = " + t.activeCount() + ", active group count = " + t.activeGroupCount() + ", ");
t.list();
}
}
static class MyThread extends Thread{
public MyThread(){}
public MyThread(ThreadGroup tg, String threadName){
super(tg, threadName);
}
@Override
public void run(){
while (true){
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出如下:
t1 Threadgroupis java.lang.ThreadGroup[name=moheqionglin,maxpri=10]
t2 Threadgroupis java.lang.ThreadGroup[name=moheqionglin,maxpri=10]
t3 Threadgroupis java.lang.ThreadGroup[name=main,maxpri=10]
moheqionglin, active count = 2, activegroupcount = 0, java.lang.ThreadGroup[name=moheqionglin,maxpri=10]
Thread[-> ,5,moheqionglin]
Thread[->| ,5,moheqionglin]
main, active count = 5, activegroupcount = 1, java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
Thread[Monitor Ctrl-Break,5,main]
Thread[Thread-0,5,main]
java.lang.ThreadGroup[name=moheqionglin,maxpri=10]
Thread[-> ,5,moheqionglin]
Thread[->| ,5,moheqionglin]
system, active count = 8, activegroupcount = 2, java.lang.ThreadGroup[name=system,maxpri=10]
Thread[Reference Handler,10,system]
Thread[Finalizer,8,system]
Thread[Signal Dispatcher,9,system]
java.lang.ThreadGroup[name=main,maxpri=10]
Thread[main,5,main]
Thread[Monitor Ctrl-Break,5,main]
Thread[Thread-0,5,main]
java.lang.ThreadGroup[name=moheqionglin,maxpri=10]
Thread[-> ,5,moheqionglin]
Thread[->| ,5,moheqionglin]
SecurityManager
负责整个JVM程序启动时进行的安全检查
可以通过-Djava.security.manager 开启安全检查
不可以通过System.setProperty(“java.security.manager”)打开因为安全检查在JVM启动过程中也要使用,可以通过SecurityManager sm=new SecurityManager();System.setSecurityManager(sm);开启。
一旦开启了安全检查,那么只有在${JAVA_HOME}/lib/security或者其他目录的配置开启了权限的才可以加载
ThreadFactory
我们创建线程可以直接通过 new Thread创建。 但是如果你想给你创建的线程统一设定某些上下文,或者线程prefix,或者线程的threadGroup等,最方便的方法就是ThreadFactory