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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。