线程池1

java 线程池几个相关类的继承结构

线程池是一种多线程的处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
线程池的优点:
(1)线程的重用
线程的创建和销毁开销很大,而使用线程池的出现增强了线程的重用性。
(2)控制并发数
(3)线程池可以对线程进行管理

  1. Executor
    最顶层接口,只定义了一个方法void execute(Runnable command)。
public interface Executor {
    void execute(Runnable command);
}

execute方法没有返回值,原因是Runnable接口中的run方法没有返回值。
ThreadPoolExecutor类中实现了execute方法。

源代码:

    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        // 获取最新的线程池数据
        int c = ctl.get();
        // 比较线程池中的worker数量和线程池的核心容量
        if (workerCountOf(c) < corePoolSize) {
            // 如果线程池中的worker数量少,直接新增一个worker。如果添加成功,直接返回。
            if (addWorker(command, true))
                return;
            // 如果添加失败,获取最新的线程池数据
            c = ctl.get();
        }
        // 如果线程池仍在运行,则把任务放到阻塞队列中等待执行。
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            // 当任务成功放入队列时,如果recheck发现线程池已经不再运行了则从队列中把任务删除
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

用户向线程池提交任务以后,线程池的执行逻辑:
(1)如果当前woker数量小于核心容量,则新建一个woker并把当前任务分配给该woker线程,成功则返回。
(2)如果第1步失败,则尝试把任务放入阻塞队列,成功则返回。
(3)如果第2步失败,则比较当前woker数量和线程池的最大容量。如果当前woker数量小于线程池的最大容量,则新建一个woker并把当前任务分配给该woker线程,成功则返回。
(4)如果第3步失败,则调用拒绝策略处理该任务。

示例:

public class Test1_Executor implements Executor {
    
        // 实现一个简单的execute方法
    public void execute(Runnable command) {
        new Thread(command).start();
    }
    
    public static void main(String[] args) {
        Test1_Executor executor = new Test1_Executor();
        executor.execute(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName() + " - test executor");// 输出Thread-0 - test executor
            }
        });
    }

}

2.ExecutorService

ExecutorService定义了很多方法,其中包括submit方法,这个方法有返回值(Future类型)。submit方法是一个重载方法,有参数类型为Runnable的,有参数类型为Callable的。
常见方法:void execute(Runnable command),<T> Future<T> submit(Callable<T> task),Future<?> submit(Runnable task),void shutdown(),List<Runnable> shutdownNow()。

3.AbstractExecutorService
抽象类,类中实现了一些方法直接供子类使用。

4.ThreadPoolExecutor


Future<V> -> RunnableFuture<V> -> FutureTask<V>
Runnable -> RunnableFuture<V>
FutureTask通过RunnableFuture间接实现了Runnable接口。每个Runnable通常会先包装成FutureTask,然后调用executor.execute(Runnable command)将其提交给线程池。

  1. Future
    未来结果,ExecutorService中的submit方法的返回值类型。
    get无参方法 - 阻塞等待线程执行结束,获取结果。
    get有参方法 - 阻塞固定时长,等待线程执行结束,获取结果;如果在阻塞的过程中,线程未执行结束,抛出异常。
    isDone方法 - 查看线程是否执行结束。

  2. Callable
    可执行接口,类似Runnable接口,也是一个可以启动线程的接口。Callable接口中定义的方法是call方法,call方法的作用和Runnable中的run方法相同,只是call方法有返回值并可以抛出异常。
    Callable只能在ExecutorService中的submit方法中使用。

ExecutorService+Future+Callable示例:

public class Test2_Future {
    
    public static void main(String[] args) throws InterruptedException, ExecutionException {    
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        
        Future<String> future = executorService.submit(new Callable<String>() {
            public String call() {
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("aaa");
                return Thread.currentThread().getName() + " - test executor";
            }
        });
        System.out.println(future);
        System.out.println(future.isDone());// 查看线程是否执行结束, 即call方法是否执行结束
        
        System.out.println(future.get());// 等待线程执行结束,获取call方法的返回值。
        System.out.println(future.isDone());
    }

}
  1. Executors
    工具类型(类似于Arrays,Collections),可以快速地创建若干种线程池。例如:固定容量的,无限容量的,容量为1的线程池。
  2. 线程池的状态
    线程池是一个进程级的重量级资源。默认它的生命周期和JVM一致。当线程池开启后,直到JVM关闭为止,是线程池的默认生命周期。
    线程池状态:Running,ShuttingDown,Terminated
    (1)Running:线程池正在执行。
    (2)ShuttingDown:线程池正在关闭,优雅关闭(执行了shutdown方法)。一旦进入这个状态,线程池不会再接收新的任务(包括等待队列中的任务),只处理所有已接收的任务,处理完毕后,线程池自动关闭。
    (3)Terminated - 线程池已经关闭。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容

  • 一.Java中的ThreadPoolExecutor类 java.uitl.concurrent.ThreadPo...
    谁在烽烟彼岸阅读 644评论 0 0
  • 昨天朋友问我,说有两个男人同时对她很好,都是奔着结婚去的,她茫然不知道该选择谁,想听听我的意见。在她眼中我是一个婚...
    如水年华阅读 505评论 0 50
  • 人,要有一颗干净的心, 才能分清黑白, 才能远离是非, 才不会被各种坏风气污染。 人,要有一颗干净的心, 才能活得...
    修源阅读 1,050评论 0 2
  • 胃疼折腾了我一夜,好不容易挨到天亮,买了药吃上,缓解了一下,本想能挨过去,下午更厉害了,去打了个点滴。给儿子...
    Summer_00d9阅读 154评论 1 2