java-线程组与线程池
线程组
Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。默认情况下,所有的线程都属于主线程组。
线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组。
允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。
ThreadGroup类
下面是截取了一部分ThreadGroup的代码:
/**
* A thread group represents a set of threads. In addition, a thread
* group can also include other thread groups. The thread groups form
* a tree in which every thread group except the initial thread group
* has a parent.
* <p>
* A thread is allowed to access information about its own thread
* group, but not to access information about its thread group's
* parent thread group or any other thread groups.
*/
public
class ThreadGroup implements Thread.UncaughtExceptionHandler {
private final ThreadGroup parent;
String name;
int maxPriority;
boolean destroyed;
boolean daemon;
boolean vmAllowSuspension;
int nUnstartedThreads = 0;
int nthreads;
Thread threads[];
int ngroups;
ThreadGroup groups[];
/**
* Creates an empty Thread group that is not in any Thread group.
* This method is used to create the system Thread group.
*/
private ThreadGroup() { // called from C code
this.name = "system";
this.maxPriority = Thread.MAX_PRIORITY;
this.parent = null;
}
...
/**
* Returns the name of this thread group.
*/
public final String getName() {
return name;
}
/**
* Returns the parent of this thread group.
* <p>
* First, if the parent is not <code>null</code>, the
* <code>checkAccess</code> method of the parent thread group is
* called with no arguments; this may result in a security exception.
*/
public final ThreadGroup getParent() {
if (parent != null)
parent.checkAccess();
return parent;
}
}
Thread类中有一个getThreadGroup方法:
public final ThreadGroup getThreadGroup():返回该线程所属的线程组。 如果该线程已经终止(停止运行),该方法则返回 null。
ThreadGroup类中有一个方法getName:
public final String getName():返回此线程组的名称。
Thread类可以指定线程组的构造方法
Thread(ThreadGroup group, Runnable target, String name)
public class MyThread {
static class MyRunnable implements Runnable {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread thread = Thread.currentThread();
System.out.println("ThreadGroup is " + thread.getThreadGroup().getName() + " >> " + thread.getName());
}
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable runnable = new MyRunnable();
ThreadGroup threadGroup = new ThreadGroup("MyThreadGroup");
threadGroup.setDaemon(true);
Thread thread1 = new Thread(threadGroup, runnable,"thread1");
Thread thread2 = new Thread(threadGroup, runnable,"thread2");
thread1.start();
thread2.start();
Thread.sleep(5000);
threadGroup.stop();
Thread.sleep(5000);
}
}
线程池
程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。
线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池
JDK5新增了一个Executors工厂类来产生线程池,有如下几个方法
public static ExecutorService newCachedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
这些方法的返回值是ExecutorService对象,该对象表示一个线程池,可以执行Runnable对象或者Callable对象代表的线程。
具体请参考我的另一篇文章:https://www.jianshu.com/p/9010465977f2