线程池executors的newsinglethreadexecutor和newfixedthreadpool(1)
与其他等效的newfixedthreadpool(1)不同
- newsinglethreadexecutor返回的执行器保证不可重新配置。
与其他等效的newscheduledthreadpool(1)不同
- newsinglethreadscheduledexecutor返回的执行器保证不可重新配置以使用其他线程。
newfixedthreadpool(1)的返回结果我们可以通过强转变成threadpoolexecutor,但是这个类是可以自行指定线程数的。
我们可以通过setcorepoolsize方法来修改。
这样也就是说,这两个方法的最大的区别是第一个方法可以修改线程的数量,如果用来指定线程数量为1是不安全的。
newsinglethreadexecutor方法则通过提供了一个包装类完全堵住了这个漏洞。
举个例子
拿newsinglethreadexecutor和newfixedthreadpool(1)举例
import org.junit.test; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import java.util.concurrent.threadpoolexecutor; public class threadpooldemo { static class myrunnable implements runnable { @override public void run() { system.out.println("开始"); try { thread.sleep(500); } catch (interruptedexception e) { e.printstacktrace(); } system.out.println("结束" + thread.currentthread().getname()); } } @test public void test() throws interruptedexception { //创建runnable实例对象 myrunnable r = new myrunnable(); //创建线程池对象 system.out.println("fixedthreadpool"); executorservice fixedthreadpool = executors.newfixedthreadpool(1);//包含1个线程对象 for (int i = 0; i < 10; i++) { fixedthreadpool.submit(r); } thread.sleep(10000); /** * 以上输出: * fixedthreadpool * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 * 开始 * 结束pool-1-thread-1 */ system.out.println("singlethreadexecutor"); executorservice singlethreadexecutor = executors.newsinglethreadexecutor(); for (int i = 0; i < 10; i++) { singlethreadexecutor.submit(r); } thread.sleep(10000); /** * 以上输出: * singlethreadexecutor * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 * 开始 * 结束pool-2-thread-1 */ system.out.println("fixedthreadpool(5)"); ((threadpoolexecutor) fixedthreadpool).setcorepoolsize(5); for (int i = 0; i < 10; i++) { fixedthreadpool.submit(r); } thread.sleep(10000); /** * 以上输出: * fixedthreadpool(5) * 开始 * 开始 * 开始 * 开始 * 开始 * 结束pool-1-thread-1 * 结束pool-1-thread-5 * 结束pool-1-thread-2 * 结束pool-1-thread-3 * 结束pool-1-thread-4 * 开始 * 结束pool-1-thread-4 * 开始 * 结束pool-1-thread-4 * 开始 * 结束pool-1-thread-4 * 开始 * 结束pool-1-thread-4 * 开始 * 结束pool-1-thread-4 * singlethreadexecutor(5) */ system.out.println("singlethreadexecutor(5)"); ((threadpoolexecutor) singlethreadexecutor).setcorepoolsize(5); for (int i = 0; i < 10; i++) { singlethreadexecutor.submit(r); } /** * 以下输出: * exception in thread "main" java.lang.classcastexception: java.util.concurrent.executors$finalizabledelegatedexecutorservice cannot be cast to java.util.concurrent.threadpoolexecutor * at threadpooldemo.main(threadpooldemo.java:33) */ } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论