美文网首页
线程池的工作原理

线程池的工作原理

作者: Wu巧不成 | 来源:发表于2017-04-05 16:51 被阅读0次

先看一个图来简单了解一下线程池的工作流程

QQ截图20170405163205.png

1.线程池创建的Thread对象,run方法会通过阻塞队列的take方法获取一个Runnable对象
2.当需要向线程池提交任务时会调用阻塞队列的offer方法向队列的尾部添加任务。
3.当Runnable对象的run方法执行完毕以后,Thread中的run方法又循环的从阻塞队列中获取下一个Runnable对象继续执行。

这样就实现了Thread对象的重复利用,也就减少了创建线程和销毁线程所消耗的资源。

我们再看一个例子

public class MyClass {

public static void main(String[] args) {

    ExecutorService threadPool = Executors.newFixedThreadPool(3);//线程池中,3工作线程
    threadPool.execute(new ThreadPoolDemo.Task("a"));
    threadPool.execute(new ThreadPoolDemo.Task("b"));
    threadPool.execute(new ThreadPoolDemo.Task("c"));
    threadPool.execute(new ThreadPoolDemo.Task("d"));
    threadPool.execute(new ThreadPoolDemo.Task("e"));
    threadPool.shutdown();

    System.out.println(threadPool.isShutdown());//是否执行了shutdown
    System.out.println(threadPool.isTerminated());//是否执行完所有的任务

    while(!threadPool.isTerminated()){
        //阻塞
    }
    System.out.println("OVER");
}

}

class ThreadPoolDemo {

static class Task implements Runnable {
    private String id;

    Task(String id) {
        this.id = id;
    }

    @Override
    public void run() {
        System.out.println("Thread " + id + " is run");
        try {
            //每个任务随机延时1s以内的时间以模拟线程的运行
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Thread " + id + " run over");
    }
}

}

执行结果
Thread b is run
Thread a is run
Thread c is run
true
false
Thread c run over
Thread d is run
Thread b run over
Thread e is run
Thread e run over
Thread d run over
Thread a run over
OVER

我们可以看到:
1.打印的方法isShutdown 和 isTerminated 分别是true 和 false,isShutdown表示是否执行了shutdown,而isTerminated 指是否执行完成所有的任务
2.线程池中固定只允许同时执行的数量为3个,所以必须前3个执行完至少一个后面的等待线程才能执行
3.因为线程是并发执行的,所以顺序是乱序的,如果想顺序可以把newFixedThreadPool(3)改为1,或者使用newSingleThreadExecutor。

相关文章

网友评论

      本文标题:线程池的工作原理

      本文链接:https://www.haomeiwen.com/subject/kxhxattx.html