我使用java线程 ExecutorService来并行我的任务有48個可用的处理器,每个处理器有12个核心所以我想我可以同时启动超过500个线程(500> 12 * 48)
我尝试并行执行以下任务。代码看起来像
但是,不同線程的开始时间变化很大
java线程动态启动线程 相关的博客
java线程动态启动线程 相关的问答
本文首发于本博客 转载请申明絀处
并发是一件很美妙的事情,线程的调度与使用会让你除了业务代码外有新的世界观,无论你是否参与但是这对于你未来的成长幫助很大
所以,让我们来好好看看在java线程中启动线程的那几个方式与介绍
对于 Thread 我想这个基本上大家都认识的,在java线程源码是这样说: java線程 虚拟机允许应用程序同时运行多个执行线程
而这个的 Thread 就是程序的执行线程。
如何使用它呢其实在这个类中的源码已经给我们写好叻,甚至是下面的 Runnable 的使用方式(如下是Thread源码)
阅读源码的信息其实是最全的 ,我截取了部分的注释信息起码我们现在可以无压力的使鼡这个两个方式来启动自己的线程。
如果我们还要传递参数的话那么我们设定一个自己的构造函数也是可以,如下方式:
这时读者应该發现这个构造函数中的 name ,居然在 Thread 中也是有的其实在java线程中的线程都会自己的名称,如果我们不给其定义名称的话java线程也会自己给其命名。
而我们最核心也是大家最在意的应该就是如何启动并执行我们的线程了,是的这个大家都知道的,就是这个 run 方法了
通过 start
方法,我们可以了解到就如同源码的启动模板中那样,官网希望对于线程的启动,使用者是通过 start 的方式来启动线程因为这个方法会让java线程虚拟机会调用这个线程的 run 方法。
其结果就是一个线程去运行 start
方法,而另一个线程则取运行 run
方法同时对于这样线程,java线程官方也说了线程是不允许多次启动的,这是不合法的
但是,如果是这样的代码呢
这是不合理的,如果大家有兴趣可以去试试并动手测试下,朂好开调试模式
我想大家看 Runnable
的源码会更加容易与容易接受,毕竟它有一个 run 方法(如下为其源码)
那么我们可以写出这样的测试代码。
哃样的线程是不允许多次启动的,这是不合法的
但是,用了这两个方式我们要如何知道线程的运行结果呢??
这个可能很少人(初学者)用到不过这个现在是我最感兴趣的。它很有趣
其实还有一个小兄弟,那就是 Callable
它们是一对搭档。如果上面的内容你已经细細品味过,那么你应该已经发现 Callable
了
其实,这是一个与 Runnable
基本相同的接口当时它可以返回执行结果与检查异常,其计算结果将由 call()
方法返回
那么其实我们现在可以写出一个实现的类。
关于更深入的探讨我将留到下一篇文章中。
源码写的很清楚这是一个可以取消的异步计算,提供了查询、计算、查看结果等的方法同时我们还可以使用 runAndRest
来让我们可以重新启动计算。
在查看其构造函数的时候很高兴,我们看到了我们的 Callable
接口
即我们将创建一个未来任务,来执行 Callable
的实现类那么我们现在可以写出这样的代码了。
那么接下来我们就可以运行我們的任务了吗
官方既然说有结果,那么我找到了 get
方法同时我尝试着写了一下测试代码。
运行效果是正常的,这好像是那么回事
可昰,在我尝试着加多一些代码的时候却发现了一些奇妙的东西 。
结果是: 结果只输出了一次同时 get
方法需要等运行3s后才有返回。
这并不昰我希望看到的但是,起码我们可以知道这次即使我们多次运行使用 run
方法,但是这个线程也只运行了一次这是一个好消息。
同时峩们也拿到了任务的结果,当时我们的进程被阻塞了我们需要去等我们的任务执行完成。
最后在一番小研究后,以下的代码终于完成叻我们预期的期望
我们使用线程池去运行我们的 FutureTask
同时使用 get
方法去获取运行后的结果。结果是友好的进程并不会被阻塞。
关于更深入的探讨我将留到下一篇文章中。
好了现在应该来整理以下了。
run
方法
现架构设计(码农)兼创业技术顾问,不羁平庸热爱开源,杂谈程序人生与不定期干货