Thread、ThreadGroup、ThreadFactory、ThreadPoolExecutor

先说Thread:

1、构造方法Thread(),调的是create()方法,

private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
        Thread currentThread = Thread.currentThread();
        if (group == null) {
            group = currentThread.getThreadGroup();
        }

        if (group.isDestroyed()) {
            throw new IllegalThreadStateException("Group already destroyed");
        }

        this.group = group;

        synchronized (Thread.class) {
            id = ++Thread.count;//--------------Thread的id是一个向上计数值。
        }

        if (threadName == null) {
            this.name = "Thread-" + id;//-------Thread的默认name是“Thread-”+id.
        } else {
            this.name = threadName;
        }

        this.target = runnable;//-----------------将构造方法中的runnable参数赋给target,将在run()方法中使用。
        this.stackSize = stackSize;

        this.priority = currentThread.getPriority();

        this.contextClassLoader = currentThread.contextClassLoader;

        // Transfer over InheritableThreadLocals.
        if (currentThread.inheritableValues != null) {
            inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
        }

        // add ourselves to our ThreadGroup of choice
        this.group.addThread(this);
    }

2、run()方法,该方法往往被覆写(通过无参构造方法初始化Thread时),或者使用传Runnable的构造方法初始化Thread.

public void run() {
        if (target != null) {
            target.run();
        }
    }
可以看到run()方法没有通过JNI调虚拟机或运行时的函数,只是普通的java方法。


3、start()方法

    public synchronized void start() {
        checkNotStarted();//-----------该方法只是避免同一Thread对象调用多次start()方法。

        hasBeenStarted = true;//-------默认值为false;

        nativeCreate(this, stackSize, daemon);
    }

    private void checkNotStarted() {
        if (hasBeenStarted) {
            throw new IllegalThreadStateException("Thread already started");//----------一个Thread对象只能调一次start()方法。
        }
    }
private native static void nativeCreate(Thread t, long stackSize, boolean daemon);//----调用虚拟机的创建线程函数,并创建一个线程。


4、相比thread.run()和thread.start()。run()方法并不会创建线程;而start()方法会创建线程,然后回调run()方法。

class vmSymbolHandles: AllStatic {
   ...
    template(run_method_name,"run");//------------------------------将run方法名,定义为run_method_name.
   ...
}
static void thread_entry(JavaThread* thread, TRAPS) {
    HandleMark hm(THREAD);
    Handle obj(THREAD, thread->threadObj());
    JavaValue result(T_VOID);
    JavaCalls::call_virtual(&result,obj,
    KlassHandle(THREAD,SystemDictionary::Thread_klass()),
                vmSymbolHandles::run_method_name(),//----------------调用run_method_name函数,即调run()方法。
                vmSymbolHandles::void_method_signature(),THREAD);
 }


5、join()方法,使当前所处线程阻塞,直到该线程(调用者线程)执行完毕。
private final Object lock = new Object();//------------------声明在当前所处线程,如:主线程。
public final void join() throws InterruptedException {
        synchronized (lock) {//------------------------------锁住当前所处线程(如:主线程)的lock对象。
            while (isAlive()) {
                lock.wait();//-------------------------------是当前所处线程(如:主线程)等待,或者说阻塞。
            }
        }
    }
wait()方法的注释:Causes the calling thread to wait until another thread calls the notify() or notifyAll() method of this object. 
public final void unpark$() {
        synchronized (lock) {
            switch (parkState) {
                case ParkState.PREEMPTIVELY_UNPARKED: {
                    /*
                     * Nothing to do in this case: By definition, a
                     * preemptively unparked thread is to remain in
                     * the preemptively unparked state if it is told
                     * to unpark.
                     */
                    break;
                }
                case ParkState.UNPARKED: {
                    parkState = ParkState.PREEMPTIVELY_UNPARKED;
                    break;
                }
                default /*parked*/: {
                    parkState = ParkState.UNPARKED;
                    lock.notifyAll();//----------------------------------这里通知lock停止等待。
                    break;
                }
            }
        }
    }


在Thread类的实例化方法create中,我们看到有ThreadGroup对象的使用,

下面说一下ThreadGroup:

1、实现关系,竟然实现自Thread的内部接口UncaughtExceptionHandler。捕捉崩溃日志公共类实现的也是Thread的这个内部接口!

public class ThreadGroup implements Thread.UncaughtExceptionHandler {

2、构造方法,parent缺省是Thread.currentThread().getThreadGroup(),

    public ThreadGroup(ThreadGroup parent, String name) {
        if (parent == null) {
            throw new NullPointerException("parent == null");
        }
        this.name = name;
        this.parent = parent;
        if (parent != null) {
            parent.add(this);
            this.setMaxPriority(parent.getMaxPriority());
            if (parent.isDaemon()) {//--------------------------继承父节点的daemon关系。
                this.setDaemon(true);
            }
        }
    }

3、addThread()方法,将Thread对象加入到一个List中,以管理。
private final List<WeakReference<Thread>> threadRefs = new ArrayList<WeakReference<Thread>>(5);
    final void addThread(Thread thread) throws IllegalThreadStateException {
        synchronized (threadRefs) {
            if (isDestroyed) {
                throw new IllegalThreadStateException();
            }
            threadRefs.add(new WeakReference<Thread>(thread));
        }
    }

这个List的初始容量为5,但并不是容量只有5,ArrayList的add(E)方法会自动扩容:

@Override public boolean add(E object) {
        Object[] a = array;
        int s = size;
        if (s == a.length) {
            Object[] newArray = new Object[s +
                    (s < (MIN_CAPACITY_INCREMENT / 2) ? //-----------------MIN_CAPACITY_INCREMENT = 12;
                     MIN_CAPACITY_INCREMENT : s >> 1)];
            System.arraycopy(a, 0, newArray, 0, s);
            array = a = newArray;
        }
        a[s] = object;
        size = s + 1;
        modCount++;
        return true;
    }
也就是说,如果list的现有容量是5,那么s=5 < 6 (12/2) ,那么就新建一个newArray容量为s+12;如果list现有容量是7,那么s=7>6,那么就新建一个newArray容量为s+3(7>>1);

4、enumerate方法,将ThreadGroup中的threads复制到参数Thread[] threads中,重载调用的是enumerateGeneric()方法,返回已复制的线程(组)个数。

private int enumerateGeneric(Object[] enumeration, boolean recurse, int enumerationIndex,
            boolean enumeratingThreads) {
        if (enumeratingThreads) {
            synchronized (threadRefs) {
                // walk the references directly so we can iterate in reverse order
                for (int i = threadRefs.size() - 1; i >= 0; --i) {
                    Thread thread = threadRefs.get(i).get();
                    if (thread != null && thread.isAlive()) {
                        if (enumerationIndex >= enumeration.length) {
                            return enumerationIndex;
                        }
                        enumeration[enumerationIndex++] = thread;//-------------enumeration为Thread[]类型时,一个个赋值给传人参数enumeration的每个元素。
                    }
                }
            }
        } else {
            synchronized (groups) {
                for (int i = groups.size() - 1; i >= 0; --i) {
                    if (enumerationIndex >= enumeration.length) {
                        return enumerationIndex;
                    }
                    enumeration[enumerationIndex++] = groups.get(i);//---------用于参数enumeration为ThreadGroup[]类型时。
                }
            }
        }

        if (recurse) {
            synchronized (groups) {
                for (ThreadGroup group : groups) {
                    if (enumerationIndex >= enumeration.length) {
                        return enumerationIndex;//-----------------------------<span style="font-family: Arial, Helvetica, sans-serif;">参数enumeration为ThreadGroup[]类型时,返回ThreadGroup的容量。</span>
                    }
                    enumerationIndex = group.enumerateGeneric(enumeration, recurse,
                            enumerationIndex, enumeratingThreads);//-----------惨呼enumeration为Thread[]时,递归调用enumerateGeneric()方法。
                }
            }
        }
        return enumerationIndex;
    }


5、list()方法,用于SystemOut方式打印日志。

    public void list() {
        // We start in a fresh line
        System.out.println();
        list(0);
    }
    private void list(int levels) {
        indent(levels);
        System.out.println(this.toString());//-----打印toString():getClass().getName() + "[name=" + getName() + ",maxPriority=" + getMaxPriority() + "]"

        ++levels;
        synchronized (threadRefs) {
            for (Thread thread : threads) {
                indent(levels);
                System.out.println(thread);//------打印"Thread[" + name + "," + priority + "," + group.getName() + "]"

            }
        }
        synchronized (groups) {
            for (ThreadGroup group : groups) {
                group.list(levels);
            }
        }
    }
    private void indent(int levels) {
        for (int i = 0; i < levels; i++) {
            System.out.print("    "); // 4 spaces for each level---------不同层级,则打印4个空格分隔。
        }
    }
总结一下,ThreadGroup是一个管理Thread的公共类,没有用到JNI,添加、移除、销毁、打印日志等功能。说到这,我们联想到线程池ThreadPoolExecutor公共类,通过ThreadGroup管理Thread,以达到对线程的实用性管理。


下面我们看一下ThreadPoolExecutor

1、execute()方法,这是执行发放,调用此方法后执行线程池里的线程,

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * Proceed in 3 steps:
         *
         * 1. If fewer than corePoolSize threads are running, try to
         * start a new thread with the given command as its first
         * task.  The call to addWorker atomically checks runState and
         * workerCount, and so prevents false alarms that would add
         * threads when it shouldn't, by returning false.
         *
         * 2. If a task can be successfully queued, then we still need
         * to double-check whether we should have added a thread
         * (because existing ones died since last checking) or that
         * the pool shut down since entry into this method. So we
         * recheck state and if necessary roll back the enqueuing if
         * stopped, or start a new thread if there are none.
         *
         * 3. If we cannot queue task, then we try to add a new
         * thread.  If it fails, we know we are shut down or saturated
         * and so reject the task.
         */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true))//----------------------------调用addWork方法来执行线程。
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }
    private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }

        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            w = new Worker(firstTask);//---------------------将Runnable firstTask,初始到Worker类中。
            final Thread t = w.thread;//---------------------Worker的属性thread是一Thread对象,赋值给t.
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();
                try {
                    // Recheck while holding lock.
                    // Back out on ThreadFactory failure or if
                    // shut down before lock acquired.
                    int rs = runStateOf(ctl.get());

                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {
                        if (t.isAlive()) // precheck that t is startable
                            throw new IllegalThreadStateException();
                        workers.add(w);
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();
                }
                if (workerAdded) {
                    t.start();//------------------------------------------Thread t调用start()方法,启动线程。
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w);
        }
        return workerStarted;
    }
Worker(Runnable firstTask) {//---------------------------------------Worker类的构造方法。
            setState(-1); // inhibit interrupts until runWorker
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);//------通过getThreadFactory的newThread方法创建线程。
        }
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);//-------------ThreadPoolExecutor的构造方法,缺省的ThreadFactory为defaultThreadFactory。
    }
public static ThreadFactory defaultThreadFactory() {
        return new DefaultThreadFactory();
    }
static class DefaultThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        DefaultThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();//---用到了ThreadGroup group.
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        }

        public Thread newThread(Runnable r) {//--------------------------------这就是上面提到的newThread方法,创建Thread对象。用到了ThreadGroup group.
            Thread t = new Thread(group, r,
                                  namePrefix + threadNumber.getAndIncrement(),
                                  0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;//--------------------------------------------------------返回Thread对象t.
        }
    }
通过上述一系列调用,我们看到,ThreadPoolExecutor缺省参数是(通过ThreadFactory公共类)用到ThreadGroup来管理线程的。

我们再联想到ThreadPoolExecutor的常用封装类AsyncTask,看看他是怎么用ThreadPoolExecutor的:

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(Runnable r) {//-------------------------------------自定义ThreadFactory,newThread方法没有用ThreadGroup!
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };

    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);

    /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     */
    public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
实际上,ThreadPoolExecutor的缓存功能,主要是阻塞队列在起作用。ThreadGroup的作用小到已被AsyncTask忽视掉。












































  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ThreadPoolExecutorthreadFactory参数是用来创建新线程的工厂。它是一个接口类型,通常需要实现ThreadFactory接口。 通过提供自定义的ThreadFactory,可以对线程的创建过程进行定制化。例如,可以设置线程的名称、优先级、是否为守护线程等。 以下是一个示例代码,展示了如何使用threadFactory参数创建一个ThreadPoolExecutor: ```java import java.util.concurrent.*; public class ThreadPoolExample { public static void main(String[] args) { // 创建自定义的ThreadFactory ThreadFactory threadFactory = new CustomThreadFactory(); // 创建ThreadPoolExecutor并指定threadFactory ThreadPoolExecutor executor = new ThreadPoolExecutor( 5, 10, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(), threadFactory); // 执行任务 for (int i = 0; i < 10; i++) { executor.execute(new Task()); } // 关闭线程池 executor.shutdown(); } static class CustomThreadFactory implements ThreadFactory { private int counter = 0; @Override public Thread newThread(Runnable r) { counter++; String threadName = "CustomThread-" + counter; return new Thread(r, threadName); } } static class Task implements Runnable { @Override public void run() { System.out.println("Task executed by " + Thread.currentThread().getName()); } } } ``` 在上述代码中,我们通过实现ThreadFactory接口创建了一个自定义的线程工厂CustomThreadFactory。在newThread方法中,我们为每个新线程设置了一个名称,并返回一个新的Thread对象。 然后,我们使用指定的threadFactory创建了一个ThreadPoolExecutor,并提交了一些任务。执行这些任务时,会由创建的线程池中的线程来执行。 注意:ThreadPoolExecutorthreadFactory参数是可选的。如果不指定threadFactory
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值