天天看點

Java使用ThreadFactory來建立新的線程

本文章參考自:https://blog.csdn.net/u012129558/article/details/80430671

在原作者的基礎上省去了一些不必要的代碼,以此進行線程工廠的學習.

首先是線程類:WorkThread.java

package com.hbu.thread;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: 申劭明
 * @Date: 2019/9/20 9:26
 */
public class WorkThread extends Thread {
    /**
     * 計數器
     */
    private AtomicInteger counter;

    /**在Thread類中,有Runnable對象
     *
     * @param target 執行的方法
     * @param counter 計數器
     */
    public WorkThread(Runnable target, AtomicInteger counter) {
        super(target);
        this.counter = counter;
    }

    @Override
    public void run() {
        int c = counter.getAndDecrement();

        try {
            //此處執行target.run()和super.run()是同樣的效果,原因可以在Thread中找到
            super.run();
            System.out.println("線程:" + c +" 執行完畢");
        }finally {
            System.out.println("結束線程:" + c);
        }
    }
}
           

線程具體執行的類:WorkRunnable.java

package com.hbu.thread;

/**
 * @Author: 申劭明
 * @Date: 2019/9/20 9:31
 */
public class WorkRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("正在執行....");
    }
}
           

線程工廠:WorkThreadFactory.java

package com.hbu.thread;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: 申劭明
 * @Date: 2019/9/20 9:32
 */
public class WorkThreadFactory implements ThreadFactory {

    /**
     * 計數器(從0開始)
     */
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    @Override
    public Thread newThread(Runnable r) {
        int c = atomicInteger.incrementAndGet();
        System.out.println("建立線程:" + c);
        return new WorkThread(r,atomicInteger);
    }
}
           

主方法:ThreadPoolTest.java

package com.hbu.thread;

import java.util.concurrent.*;

/**
 * @Author: 申劭明
 * @Date: 2019/9/20 9:05
 */
public class ThreadPoolTest {

    public static void main(String[] args) {

        //建立線程(并發)池,自動伸縮(自動控制線程池的大小)
        ExecutorService es = Executors.newCachedThreadPool(new WorkThreadFactory());

        //線程并發數量
        int concurrent = 5;

        //同時并發5個工作線程
        for (int i = 0; i < concurrent; i++) {
            es.execute(new WorkRunnable());
        }
        //訓示當所有線程執行完畢後關閉線程池和工作線程,如果不調用此方法,jvm不會自動關閉
        es.shutdown();

        try {
            //等待線程執行完畢,不能超過2 * 60秒,配合shutDown
            es.awaitTermination(2 * 50, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
           

另外,阿裡規範上規定了建立線程池時的一系列問題,例如推薦你用線程工廠去建立線程:

Java使用ThreadFactory來建立新的線程