ThreadGroup解讀


我們的項目用到了ThreadGroup 把thread放到了threadGroup中,名稱統一起來了;

    private static final ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(16, 32,
            5L, TimeUnit.MINUTES,
            new ArrayBlockingQueue<>(1000), new ThreadFactory() {

        private final ThreadGroup threadGroup = new ThreadGroup("fileTemplateMethodThreadGroup");

        private final AtomicInteger threadNumber = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(threadGroup, r, "fileTemplateMethod-thread-pool-" + threadNumber.getAndIncrement());
        }
    }, (r, executor) -> {
        if (!executor.isShutdown()) {
            /* 丟棄隊列最老的數據 */
            if (executor.getQueue().poll() != null) {
                Cat.logMetricForCount(CatConstant.METRIC_DISCARD_FILE_TASK_COUNT);
            }
            executor.execute(r);
        }
    });

ThreadGroup 可以把thread的名字統一起來。一起處理catch。

ThreadGroup是Java提供的一種對線程進行分組管理的手段,可以對所有線程以組為單位進行操作,如設置優先級、守護線程等。

線程組也有父子的概念,如下圖:

線程組的創建 

public class ThreadGroupCreator {                                              
                                                                               
    public static void main(String[] args) {                                   
        //獲取當前線程的group                                                         
        ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();    
        //在當前線程執行流中新建一個Group1                                                  
        ThreadGroup group1 = new ThreadGroup("Group1");                        
        //Group1的父線程,就是main線程所在Group                                           
        System.out.println(group1.getParent() == currentGroup);                
        //定義Group2, 指定group1為其父線程                                              
        ThreadGroup group2 = new ThreadGroup(group1, "Group2");                
        System.out.println(group2.getParent() == group1);                      
    }                                                                          
}                                                                              

 

ThreadGroup是位於java.lang包下的一個類,用於統一的線程管理.一旦一個線程加入到一個線程組后,就不能更換線程所在的線程組

將當前線程加入到線程組中

public class ThreadGroupCreator {                                              
                                                                               
    public static void main(String[] args) {                                   
        //獲取當前線程的group                                                         
        ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();    
        //在當前線程執行流中新建一個Group1                                                  
        ThreadGroup group1 = new ThreadGroup("Group1");                        
        //Group1的父線程,就是main線程所在Group                                           
        System.out.println(group1.getParent() == currentGroup);                
        //定義Group2, 指定group1為其父線程                                              
        ThreadGroup group2 = new ThreadGroup(group1, "Group2");                
        System.out.println(group2.getParent() == group1);                      
    }                                                                          
}                                                                              

 


將ThreadGroup中活躍的線程引用復制到線程組

Thread[] threads = new Thread[num];
threadGroup.enumerate(threads);
for (Thread t : threads) {
System.out.println("線程名-" + t.getName());
}

 

 
測試源代碼如下

public class MyThread implements Runnable {

@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " -> start");
TimeUnit.SECONDS.sleep(10);
//隨機發生異常
if (ThreadLocalRandom.current().nextInt(10) > 5) {
throw new RuntimeException(Thread.currentThread().getName() + "發生異常");
}
System.out.println(Thread.currentThread().getName() + " -> end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
 
 

 

public class ThreadGroupTest {
public static void main(String[] args) {
int num = 10;
ThreadGroup threadGroup = new ThreadGroup("test-group") {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("ThreadGroup捕獲到線程異常 - " + e.getMessage());
}
};

List<Thread> threadList = new ArrayList<>();
for (int i = 0; i < num; i++) {
Thread thread = new Thread(threadGroup, new MyThread(), "threadname-" + i);
threadList.add(thread);
}

System.out.println("運行前線程組中活躍線程數 -> " + threadGroup.activeCount());
System.out.println("開始運行所有線程...");
for (Thread t : threadList) {
t.start();
}
//獲取線程組中所有[活動]線程
Thread[] threads = new Thread[num];
threadGroup.enumerate(threads);
for (Thread t : threads) {
System.out.println("線程名-" + t.getName());
}
System.out.println("所有線程運行后,線程組中活躍線程數-" + threadGroup.activeCount());
//不斷的查看線程組中活躍的線程數
Thread thread = new Thread(() -> {
int num1;
try {
while ((num1 = threadGroup.activeCount()) > 0) {
System.out.println("當前線程組活躍線程數為 -> " + num1);
TimeUnit.SECONDS.sleep(1);
}
System.out.println("All Thread HAS FINISHED");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
}
}

 

運行結果如下

運行前線程組中活躍線程數 -> 0
開始運行所有線程...

threadname-0 -> start
threadname-1 -> start
threadname-2 -> start
threadname-3 -> start
threadname-4 -> start
threadname-5 -> start
threadname-6 -> start
threadname-7 -> start
threadname-8 -> start
線程名-threadname-0
threadname-9 -> start
線程名-threadname-1
線程名-threadname-2
線程名-threadname-3
線程名-threadname-4
線程名-threadname-5
線程名-threadname-6
線程名-threadname-7
線程名-threadname-8
線程名-threadname-9
所有線程運行后,線程組中活躍線程數-10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
當前線程組活躍線程數為 -> 10
threadname-5 -> end
threadname-8 -> end
ThreadGroup捕獲到線程異常 - threadname-7發生異常
ThreadGroup捕獲到線程異常 - threadname-2發生異常
threadname-4 -> end
ThreadGroup捕獲到線程異常 - threadname-3發生異常
ThreadGroup捕獲到線程異常 - threadname-9發生異常
ThreadGroup捕獲到線程異常 - threadname-1發生異常
threadname-6 -> end
threadname-0 -> end
All Thread HAS FINISHED
--------------------- 

 


 

 

線程組的基本操作

注意:后添加進線程組的線程,其優先級不能大於線程組的優先級 

public class ThreadGroupBasic {                                                      
                                                                                     
    public static void main(String[] args) throws InterruptedException {             
                                                                                     
        ThreadGroup group = new ThreadGroup("group1");                               
        Thread thread = new Thread(group, () -> {                                    
            while(true) {                                                            
                try {                                                                
                    TimeUnit.SECONDS.sleep(1);                                       
                } catch (InterruptedException e) {                                   
                    e.printStackTrace();                                             
                }                                                                    
            }                                                                        
        }, "thread");                                                                
        thread.setDaemon(true);                                                      
        thread.start();                                                              
                                                                                     
        TimeUnit.MILLISECONDS.sleep(1);                                              
                                                                                     
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();             
        //遞歸獲取mainGroup中活躍線程的估計值                                                     
        System.out.println("activeCount = " + mainGroup.activeCount());              
        //遞歸獲mainGroup中的活躍子group                                                     
        System.out.println("activeGroupCount = " + mainGroup.activeGroupCount());    
        //獲取group的優先級, 默認為10                                                         
        System.out.println("getMaxPriority = " + mainGroup.getMaxPriority());        
        //獲取group的名字                                                                 
        System.out.println("getName = " + mainGroup.getName());                      
        //獲取group的父group, 如不存在則返回null                                                
        System.out.println("getParent = " + mainGroup.getParent());                  
        //活躍線程信息全部輸出到控制台                                                             
        mainGroup.list();                                                            
        System.out.println("----------------------------");                          
        //判斷當前group是不是給定group的父線程, 如果兩者一樣,也會返回true                                   
        System.out.println("parentOf = " + mainGroup.parentOf(group));               
        System.out.println("parentOf = " + mainGroup.parentOf(mainGroup));           
                                                                                     
    }                                                                                
                                                                                     
}                                                                                    

 

線程組的Interrupt 

public class ThreadGroupInterrupt {                                                     
                                                                                       
    public static void main(String[] args) throws InterruptedException {               
        ThreadGroup group = new ThreadGroup("TestGroup");                              
        new Thread(group, () -> {                                                      
            while(true) {                                                              
                try {                                                                  
                    TimeUnit.MILLISECONDS.sleep(2);                                    
                } catch (InterruptedException e) {                                     
                    //received interrupt signal and clear quickly                      
                    System.out.println(Thread.currentThread().isInterrupted());        
                    break;                                                             
                }                                                                      
            }                                                                          
            System.out.println("t1 will exit");                                        
        }, "t1").start();                                                              
        new Thread(group, () -> {                                                      
            while(true) {                                                              
                try {                                                                  
                    TimeUnit.MILLISECONDS.sleep(2);                                    
                } catch (InterruptedException e) {                                     
                    //received interrupt signal and clear quickly                      
                    System.out.println(Thread.currentThread().isInterrupted());        
                    break;                                                             
                }                                                                      
            }                                                                          
            System.out.println("t2 will exit");                                        
        }, "t2").start();                                                              
        //make sure all threads start                                                  
        TimeUnit.MILLISECONDS.sleep(2);                                                
                                                                                       
        group.interrupt();                                                             
    }                                                                                  
                                                                                       
}                                                                                      

 

線程組的destroy 

public class ThreadGroupDestroy {                                             
                                                                              
    public static void main(String[] args) {                                  
        ThreadGroup group = new ThreadGroup("TestGroup");                     
        ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();      
        //before destroy                                                      
        System.out.println("group.isDestroyed=" + group.isDestroyed());       
        mainGroup.list();                                                     
                                                                              
        group.destroy();                                                      
        //after destroy                                                       
        System.out.println("group.isDestroyed=" + group.isDestroyed());       
        mainGroup.list();                                                     
    }                                                                         
                                                                              
}                                                                             

 

線程組設置守護線程組

線程組設置為守護線程組,並不會影響其線程是否為守護線程,僅僅表示當它內部沒有active的線程的時候,會自動destroy

public class ThreadGroupDaemon {                                               
                                                                               
    public static void main(String[] args) throws InterruptedException {       
        ThreadGroup group1 = new ThreadGroup("group1");                        
        new Thread(group1, () -> {                                             
            try {                                                              
                TimeUnit.SECONDS.sleep(1);                                     
            } catch (InterruptedException e) {                                 
                e.printStackTrace();                                           
            }                                                                  
        }, "group1-thread1").start();                                          
        ThreadGroup group2 = new ThreadGroup("group2");                        
        new Thread(group2, () -> {                                             
            try {                                                              
                TimeUnit.SECONDS.sleep(1);                                     
            } catch (InterruptedException e) {                                 
                e.printStackTrace();                                           
            }                                                                  
        }, "group1-thread2").start();                                          
        group2.setDaemon(true);                                                
                                                                               
        TimeUnit.SECONDS.sleep(3);                                             
        System.out.println(group1.isDestroyed());                              
        System.out.println(group2.isDestroyed());                              
    }                                                                          
}                                                                              

 

 

 
 參考: Java並發編程之ThreadGroup
參考: ThreadGroup解讀


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM