纪念一下自己理解成渣的线程池

        线程池(ThreadPoolExecutor)的理解,网上百度一下一大片,而我也看过很多。不知道是不是自己每次看的都太快,很多东西总是理解的有很大的偏差,于是,被狠狠的打击了。

        首先,核心线程池(corePoolSize)没有任务是不会创建线程的,当然你可以调用prestartCoreThread()方法提前start一个线程,或者prestartAllCoreThreads()提前创建所有的核心线程。当然也可以不用搭理,让线程跟着任务慢慢创建出来的。最大线程池(maximumPoolSize),是先将任务放入缓存,只有等缓冲满了,然后才会考虑去创建线程,这时候才会用到最大线程池。而且核心线程的数量和最大线程池数量共享。也就是最大线程是核心线程池 + n = 最大。。。

        写到这里,我先讲一下写这些的原因,没错,我是前几天才理解过来的。我以前怎么理解的呢?

        嗯,我可是傻傻的把最大线程池定义过小于核心池的男人,然后直接报错。如果缓冲池不满,就不会创建新的线程,这一点我也理解成了先创建最大线程,然后再去填充线程缓存。。嗯嗯。所以说我是一个渣。希望没人和我一样渣。

        然后线程池的超时时间和缓存队列以及拒绝措施,这里我倒是还好,超时是对应着最大线程-核心线程的那部分线程的,如果想让核心线程跟着一起灭亡,ok,我们也有方法,allowCoreThreadTimeOut就是干这个事的,让创建线程池对应的超时时间对核心线程有效,记得参数是true。当然,如果不设置timeout时间有什么影响呢,你可以试试main方法启动线程池,然后等待线程结束所有的任务,然后就懂了。没错,有几个线程一直处于准备状态。很无奈吧,没事,线程池有自己的shutdown方法,他是可以慢慢干掉自己肚子里面的核心线程的,所以线程池也是需要释放的,如果需要的话。如果你是一个暴力的人,你也可以直接shutdownnow,线程池就会马上埋掉自己,即使是任务还没有完成。嗯嗯,所以线程池是很听话的。因为你都不在乎自己的任务可不可以完成了,那么他还在乎什么呢。

        到这里,其实我的渣渣体验也结束了,随便说一点自己一直都能理解正确的东西。future,没错,这个东西我都一直理解对了。

        如果调用的是submit,ok,恭喜你,你有权利将其中的每个线程单独干掉。因为submit返回的就是future对象,通过get获取结果,这个是阻塞的,也就是等待完成。。通过cancel,可以单独干掉其中单个线程,不论是否完成计算,如果是在sleep状态,简单,interrupt it,然后给你一个异常,如果在干其他的事,简单,不干了,洗洗睡吧。当然,如果你比较友善,你可以先问问,iscancel,放心,这个即使在你调用cancel之后也可以问问。最后isdone就是问问,你完成了没,没有告诉我一声,我不会对你做什么的。

        ps:java8很不出意外的出现了lambda表达式,这是一个让人无法拒绝他的原意之一。对于线程池有一点可以说一下,这个也是我没事实验出来的。线程池有一个方法叫做submit,对没错,就是我上面说的方法,他其实可以传入两种对象,一种是实现了Runnable的,这个对于初学者很常见的创建线程对象的方法了。另一个就是实现了callable的对象,Callable是什么呢,完全可以理解成就是Runnable的一个补充,一个可以有返回值和可以抛异常的run方法,当然人家名字是call方法。这里,如果使用lambda表达式,这两个方法都是无参方法,lambda怎么推断他的传入类型呢?

        没错,根据返回值。默认匹配的就是run方法。当然如果有return ,而且还不能是return ; 那么就是匹配的是call方法。我去,当然老师说了,方法匹配(方法重载)使用的是参数的类型和个数匹配的,和返回值无关,恩恩,没错。但是,这里传入的不是方法,可以理解成是对象,当然最主要的是,这里走的不是方法重载(自己想想重载是怎么定义的)。好吧,我这个渣渣,在这里差点也被迷惑了。

        最后,加油吧,我自己。2333333。

你可能感兴趣的:(纪念一下自己理解成渣的线程池)