天天看点

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来创建新的线程