有点纠结线程池的一些概念

线程池中任务和线程严格上有什么区别?

比如
Thread t1 = new Thread();
t1.start();
这里我们可以叫t1是一个线程对象。

...
Thread t2 = new Thread();
executorService.execute(t2);
这里t2是提交到线程池的任务。
这个任务是否可以理解为“未运行的线程任务”?

阅读 1.9k
3 个回答

我觉得很简洁明了,任务就是一个Runnable对象,等着被线程调度执行的。你上面说的t2就是提交的一个任务。他是一个Thread 实例,但是在线程池里面还是被当做是一个Runnable对象。t1可以说是线程对象,只是它调度的是自己内部的任务。
代码位置:Thread#run()

    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

线程池的源码,你也可以点进去看看.

public interface Executor {

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the {@code Executor} implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}

你传进来的参数Runnable对象就是提交给线程池的任务。
任务传进来之后会根据线程池的策略来决定是创建线程资源去执行还是放入队列等待调度或者其他策略,
具体的任务被执行的代码可以看ThreadPoolExecutor#runWorker(Worker w) 方法,

    final void runWorker(Worker w) {
        Thread wt = Thread.currentThread();
        Runnable task = w.firstTask;
        w.firstTask = null;
        w.unlock(); // allow interrupts
        boolean completedAbruptly = true;
        try {
            while (task != null || (task = getTask()) != null) {
                w.lock();
                // If pool is stopping, ensure thread is interrupted;
                // if not, ensure thread is not interrupted.  This
                // requires a recheck in second case to deal with
                // shutdownNow race while clearing interrupt
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
                try {
                    beforeExecute(wt, task);
                    Throwable thrown = null;
                    try {
                        // 这里执行了任务
                        task.run();
                    } catch (RuntimeException x) {
                        thrown = x; throw x;
                    } catch (Error x) {
                        thrown = x; throw x;
                    } catch (Throwable x) {
                        thrown = x; throw new Error(x);
                    } finally {
                        afterExecute(task, thrown);
                    }
                } finally {
                    task = null;
                    w.completedTasks++;
                    w.unlock();
                }
            }
            completedAbruptly = false;
        } finally {
            processWorkerExit(w, completedAbruptly);
        }
    }

t2 还是个线程对象啊。

只不过何时执行 t2.start() 是由线程池内部决定的了,不是你代码触发的了。

t2还是一个线程对象,从线程的生命周期来说,属于新建状态的线程,至于转换为就绪状态的时机(线程的start方法)由线程池决定

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题