ThreadFactory接口中定义的java.util.concurrent包是基于工厂设计模式。顾名思义,它用于按需创建新线程。线程可以通过两种方式创建:
1. 创建一个扩展类Java.lang.Thread类,然后创建它的对象。
Java
import java.io.*;
class GFG {
public static void main(String[] args)
{
// Creating a thread
Thread thread = new CustomThread();
thread.start(); // Starting execution of the created
// thread
}
}
// Creating a class that extends the Thread class
class CustomThread extends Thread {
@Override public void run()
{
System.out.println("This is a thread");
}
}
This is a thread
2. 创建一个类来实现Runnable然后使用它的对象来创建线程。
Java
/*package whatever //do not write package name here */
import java.io.*;
class GFG {
public static void main(String[] args)
{
// Creating a Runnable object
Runnable task = new Task();
// Creating a thread using the Runnable object
Thread thread = new Thread(task);
// Starting the execution of the created thread
thread.start();
}
}
class Task implements Runnable {
@Override public void run()
{
System.out.println("This is a thread");
}
}
This is a thread
然而,ThreadFactory是创建新线程的另一种选择。该接口提供了一个工厂方法调用时创建并返回新线程。这个工厂方法需要一个Runnable对象作为参数并使用它创建一个新线程。
ThreadFactory的层次结构
java.util.concurrent ↳ Interface ThreadFactory
ThreadFactory接口的实现
由于ThreadFactory是一个接口,因此必须首先实现其中定义的工厂方法才能使用。以下是 ThreadFactory 接口的最简单实现:
Java
import java.util.concurrent.ThreadFactory;
import java.io.*;
class CustomThreadFactory implements ThreadFactory {
// newThread is a factory method
// provided by ThreadFactory
public Thread newThread(Runnable command)
{
return new Thread(command);
}
}
现在,我们可以创建CustomThreadFactory类的对象,并使用其newThread(Runnable command)方法按需创建新线程。在上面的实现中,newThread方法只是通过调用以Runnable命令作为参数的Thread构造函数来创建一个新线程。
有很多类(例如ScheduledThreadPoolExecutor,ThreadPoolExecutor等),在需要时使用线程工厂创建新线程。这些类具有接受 ThreadFactory 作为参数的构造函数。如果未给出任何自定义 ThreadFactory,则它们使用 ThreadFactory 接口的默认实现。
java.util.concurrent 包中的 Executors 类提供了 Executors.defaultThreadFactory() 静态方法,该方法返回 ThreadFactory 接口的默认实现。
例子:下面的示例代码演示了ThreadFactory接口。
Java
// Java code to demonstrate ThreadFactory interface
import java.util.concurrent.ThreadFactory;
import java.io.*;
import java.util.ArrayList;
class ThreadFactoryExample {
public static void main(String[] args)
{
// Creating a CustomThreadFactory object
CustomThreadFactory threadFactory
= new CustomThreadFactory();
// Creating Runnable objects using the lambda
// expression
Runnable command1 = ()
-> System.out.println("Command 1 executed");
Runnable command2 = ()
-> System.out.println("Command 2 executed");
Runnable command3 = ()
-> System.out.println("Command 3 executed");
Runnable command4 = ()
-> System.out.println("Command 4 executed");
Runnable command5 = ()
-> System.out.println("Command 5 executed");
// Putting the commands in an ArrayList
ArrayList<Runnable> array = new ArrayList<>(5);
array.add(command1);
array.add(command2);
array.add(command3);
array.add(command4);
array.add(command5);
// creating threads and running them
for (Runnable command : array) {
threadFactory.newThread(command).start();
}
// print the thread count
System.out.println(
"Total number of threads created using CustomThreadFactory = "
+ threadFactory.getCount());
}
}
// ThreadFactory class
class CustomThreadFactory implements ThreadFactory {
// stores the thread count
private int count = 0;
// returns the thread count
public int getCount() { return count; }
// Factory method
@Override
public Thread newThread(Runnable command)
{
count++;
return new Thread(command);
}
}
Command 1 executed Command 2 executed Command 4 executed Command 3 executed Command 5 executed Total number of threads created using CustomThreadFactory = 5
为什么要使用ThreadFactory?
在上面的示例中,newThread(Runnable) 工厂方法最终使用给定的 Runnable 命令创建一个新线程。那为什么要使用ThreadFactory呢?我们可以通过调用 newThread(Runnable) 方法中的 Thread 构造函数,直接从 Runnable 命令创建线程。以下是一些原因,
- 我们可以给线程赋予更有意义的自定义名称。它有助于分析它们的目的和它们的工作方式。
- 我们可以获得有关创建的线程的统计信息,例如线程数和其他详细信息。我们可以根据统计信息限制新线程的创建。
- 我们可以设置线程的守护进程状态。
- 我们可以设置线程优先级。
- 我们可以将所有函数限制在一个类中。
默认线程工厂
它是由以下实现的默认线程工厂执行者.defaultThreadFactory()静态方法。这个默认的 ThreadFactory 被许多类使用(例如ScheduledThreadPoolExecutor,ThreadPoolExecutor等)当他们没有得到任何自定义 ThreadFactory 时。这些类使用默认的 ThreadFactory 创建新线程。默认ThreadFactory 在同一个线程中创建所有新线程Java.lang.ThreadGroup(ThreadGroup 代表一组线程)。所有创建的新线程都是非守护线程,其优先级设置为 Thread.NORM_PRIORITY 中的最小值和 ThreadGroup 中允许的最大优先级。默认 ThreadFactory 创建的线程的名称形式为pool-N-thread-M(例如,pool-1-thread-1、pool-1-thread-2、pool-2-thread-1 等)N是该工厂的序列号,并且M是该工厂创建的线程的序列号。
例子:下面的示例演示了如何使用默认的ThreadFactory。
Java
// Java program to demonstrate default
// ThreadFactory
import java.io.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
class DefaultThreadFactoryExample {
public static void main(String[] args)
{
// Default ThreadFactory
ThreadFactory threadFactory
= Executors.defaultThreadFactory();
for (int i = 1; i < 10; i++) {
// Creating new threads with the default
// ThreadFactory
Thread thread
= threadFactory.newThread(new Command());
// print the thread names
System.out.println(
"Name given by threadFactory = "
+ thread.getName());
// run the thread
thread.start();
}
}
}
class Command implements Runnable {
@Override public void run()
{
// Run some code
}
}
Name given by threadFactory = pool-1-thread-1 Name given by threadFactory = pool-1-thread-2 Name given by threadFactory = pool-1-thread-3 Name given by threadFactory = pool-1-thread-4 Name given by threadFactory = pool-1-thread-5 Name given by threadFactory = pool-1-thread-6 Name given by threadFactory = pool-1-thread-7 Name given by threadFactory = pool-1-thread-8 Name given by threadFactory = pool-1-thread-9
请注意默认 ThreadFactory 给出的线程名称。它创建了9个线程,并且所有线程都在同一个ThreadGroup中。所有线程都是使用相同的 ThreadFactory 创建的(因此线程的名称采用以下形式)池-1-thread-M)。
例子:
Java
// Java program to demonstrate ThreadFactory
// using default implementation
import java.io.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
class DefaultThreadFactoryExample {
public static void main(String[] args)
{
for (int i = 1; i < 10; i++) {
// Default ThreadFactory
ThreadFactory threadFactory
= Executors.defaultThreadFactory();
// Creating new threads with the default
// ThreadFactory
Thread thread
= threadFactory.newThread(new Command());
// print the thread name
System.out.println(
"Name given by threadFactory = "
+ thread.getName());
// start the thread
thread.start();
}
}
}
class Command implements Runnable {
@Override public void run()
{
// Run some code
}
}
Name given by threadFactory = pool-1-thread-1 Name given by threadFactory = pool-2-thread-1 Name given by threadFactory = pool-3-thread-1 Name given by threadFactory = pool-4-thread-1 Name given by threadFactory = pool-5-thread-1 Name given by threadFactory = pool-6-thread-1 Name given by threadFactory = pool-7-thread-1 Name given by threadFactory = pool-8-thread-1 Name given by threadFactory = pool-9-thread-1
在这里,我们使用了 9 个不同的默认 ThreadFactories(在每个循环中我们都创建一个新的!)。因此每个线程都位于不同的ThreadGroup中,因此线程的名称以pool-N-thread-1的形式给出。
默认的 ThreadFactory 实现创建具有正常优先级的非守护线程,并以 pool-N-thread-M 的形式给出名称,其中不包含有关它们如何工作和做什么的信息。这会在调试和其他重要目的中产生很多问题。然而,这个问题可以使用自定义ThreadFactory来解决,它可以为线程提供更有意义的名称,并可以设置守护进程和优先级状态。
ThreadFactory的方法
METHOD |
DESCRIPTION |
---|---|
newThread(Runnable r) | 构造一个新线程。 |
相关用法
- Java Thread activeCount()用法及代码示例
- Java Thread checkAccess()用法及代码示例
- Java Thread currentThread()用法及代码示例
- Java Thread destroy()用法及代码示例
- Java Thread dumpStack()用法及代码示例
- Java Thread enumerate()用法及代码示例
- Java Thread getContextClassLoader()用法及代码示例
- Java Thread getDefaultUncaughtExceptionHandler()用法及代码示例
- Java Thread getId()用法及代码示例
- Java Thread getName()用法及代码示例
- Java Thread getPriority()用法及代码示例
- Java Thread getStackTrace()用法及代码示例
- Java Thread getState()用法及代码示例
- Java Thread getThreadGroup()用法及代码示例
- Java Thread holdLock()用法及代码示例
- Java Thread interrupt()用法及代码示例
- Java Thread interrupted()用法及代码示例
- Java Thread isAlive()用法及代码示例
- Java Thread isDaemon()用法及代码示例
- Java Thread isInterrupted()用法及代码示例
- Java Thread join()用法及代码示例
- Java Thread notify()用法及代码示例
- Java Thread notifyAll()用法及代码示例
- Java Thread resume()用法及代码示例
- Java Thread run()用法及代码示例
注:本文由纯净天空筛选整理自samufo大神的英文原创作品 ThreadFactory Interface in Java with Examples。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。