Java 中线程内的线程?
我目前正在考虑如何用Java设计一个需要进行一些繁重的网络处理和数据库存储的多线程系统。该程序首先将启动三个基本线程。沿着这些基本线程,我想不是从主程序而是从两个线程启动其他线程。一个线程是否有可能启动另一个线程,从而导致某种层次结构,例如:
> Parent ->t0 thread1 -> t1 tread1.1
> ->t0 thread2
> ->t0 thread3 -> t2 thread3.1
t0= inital time
t1,t2 = time at a point in the running thread
t1 != t2
如果没有,有人可以提供带有参考的理论解决方案吗?
I am currently thinking about how to design a multithreading system in Java that needs to do some heavy network processing and database storage. The program will launch three basic threads at first. Along these basic threads, I would like to launch other threads not from the main program but from two of the threads. Is it possible for a thread to launch another thread leading to some sort of a hierarchy like:
> Parent ->t0 thread1 -> t1 tread1.1
> ->t0 thread2
> ->t0 thread3 -> t2 thread3.1
t0= inital time
t1,t2 = time at a point in the running thread
t1 != t2
If not could somebody provide a theoretical solution with references?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,您可以根据需要启动任意数量的线程,但这可能不是最好的方法。最好使用非阻塞 API,这样您就可以开始执行某些外部调用,并且调用线程可以立即开始执行其他操作,而无需等待套接字/数据库调用返回。然后,当套接字/数据库调用返回时,将触发回调以完成该处理。
非阻塞 I/O 可以提供更高的 CPU 利用率,因为您只需触发调用并注册回调,而不必尝试平衡“正确”数量的并发线程,而这些线程大多只是处于睡眠状态。
http://www.owlmountain.com/tutorials/NonBlockingIo.htm
http://www。 tensegrity.hellblazer.com/2008/03/non-blocking-jdbc-non-blocking-servlet-apis-and-other-high-mysteries.html
Yes, you can launch as many threads as you want, but that's probably not the best way to go. It's much better to use the non-blocking API's so that you can start execution of some external call and the calling thread can immediately start doing something else without waiting on the socket/database call to come back. Then, when the socket/database call comes back, a callback is triggered to finish that processing.
Non-blocking I/O can provide far superior CPU utilization since you're just triggering calls and registering callbacks and not having to try to balance the "right" number of concurrent threads which are mostly just sleeping anyways.
http://www.owlmountain.com/tutorials/NonBlockingIo.htm
http://www.tensegrity.hellblazer.com/2008/03/non-blocking-jdbc-non-blocking-servlet-apis-and-other-high-mysteries.html
要回答这个问题,是的,线程可以启动其他线程。
等级制度重要吗?
您最好使用 ExecutorService 带有缓存线程池。这样你就可以池化线程而不是创建很多线程(这很昂贵)。 ExecutorServices 还提供了其他很酷的东西,并且将 Callables / Runnables 与它们一起使用可能比自己处理线程更容易测试。
To answer the question, yes threads can launch other threads.
Is the hierarchy important?
You're probably better off using an ExecutorService with a cached thread pool. That way you can pool threads instead of creating lots (which is expensive). ExecutorServices also provide other cool things, and using Callables / Runnables with them is probably much easier to test than mucking about with threads on your own.
是的,一个线程可以启动另一个线程,并且该线程可以启动线程等等...
在线程的 run() 方法中 - 您可以创建并启动其他线程。
Yes a thread can launch another thread, and that thread can launch thread(s) and on and on...
In the
run()
method of a thread - you can create and start other threads.这是可能的
例如,您可以创建线程并将 id 放入数组中,如下所示
供给 subMainThread 之后,
在您可以将数组选项卡提
这里是线程的简单使用示例:
http://kamel.berrayah.com/wordpress/2013/07/java-线程/
It's possible
for exemple you can creat thread and put id in array like this
After you can give to the subMainThread the array tab
exemple
here a simple use of thread :
http://kamel.berrayah.com/wordpress/2013/07/java-threads/
ExecutorService
Java 5 带来了 Executors 框架。一些漂亮的接口和类将我们 Java 程序员从处理线程的乏味中解放出来。相反,我们可以将任务定义为
Runnable
或Callable
,并将这些对象交给执行器服务,以便由任意数量的后台线程最终执行。没有嵌套线程的示例
在讨论嵌套线程之前,让我们创建一个仅包含一层后台线程的示例。
我们使用单个
ExecutorService
运行三个线程,如您的问题所示。一个线程将执行一项简单的任务。另外两个线程将各自执行一项冗长的任务,其中包括一些网络处理,然后是一些数据库存储。我们通过调用 Thread.sleep 来模拟冗长的工作。
然后我们实例化一些任务,第一个 Runnable 类的一个实例和第二个 Runnable 类的两个实例。
接下来我们建立一个执行器服务来执行这些任务。 < code>Executors 实用程序类有许多方法可以使用具有各种行为的各种实现来实例化
ExecutorService
。如今,我们通常应该使用执行器服务,为每个任务创建一个新的虚拟线程。虚拟线程“便宜”,因为它们比平台线程使用更少的内存和 CPU。从 Java 21 开始,虚拟线程是合适的。 22 如果您的任务满足三个条件:
synchronized
块内没有长时间运行的代码。重要提示:请注意
ExecutorService
是自动关闭
。因此,我们可以使用 try-with-resources 语法来方便地等待所有提交的任务完成,然后自动关闭我们的执行器服务。
将这些代码放在一起。
运行时。注意经过的时间为 6 秒。
嵌套线程的示例
我们现在可以修改示例以使用嵌套线程。我们可以将每个
NetworkProcessingAndDatabaseStorage
任务作为子任务在另外两个线程上同时执行,而不是先执行网络访问,然后再执行数据库存储。我们只需实例化更多 ExecutorService 对象就可以实现这一点。更改 NetworkProcessingAndDatabaseStorage 来实例化、使用和关闭执行程序服务。
运行时,请注意运行时间如何从 6 秒缩短到 4 秒。它们不是网络处理花费 4 秒,数据库存储花费 2 秒,总共 6 秒,而是在多核机器上并行运行,总共 4 秒。
ExecutorService
Java 5 brought the Executors framework. Some nifty interfaces and classes relieves us Java programmers from the tedium of juggling threads. Instead, we could define a task as a
Runnable
orCallable
, and hand those objects over to an executor service for eventual execution by any number of background threads.Example without nesting threads
Before getting to your nested threads, let's create an example with just one level of background threads.
We use a single
ExecutorService
to run three threads, as dictated by your Question. One thread will perform a simple tasks. Two other threads will each perform a lengthy task composed of some network processing and then some database storage.We simulate the lengthy work by calling
Thread.sleep
.Then we instantiate some tasks, one instance of the first
Runnable
class, and two instances of the secondRunnable
class.Next we establish an executor service to execute these tasks. The
Executors
utility class has many methods to instantiate anExecutorService
using various implementations with various behaviors.Nowadays, we should generally use an executor service that creates a new virtual thread for each task. Virtual threads are "cheap" in that they use less memory and CPU than platform threads. A virtual thread is appropriate as of Java 21 & 22 if your task meets three criteria:
synchronized
block.Important: Note that
ExecutorService
isAutoCloseable
. So, we can use try-with-resources syntax to conveniently wait until all submitted tasks are done, then automatically close our executor service.Put that code together.
When run. Notice an elapsed time of 6 seconds.
Example with nesting threads
We can now modify our example to make use of nested threads. Instead of each of our
NetworkProcessingAndDatabaseStorage
tasks doing the network access and then subsequently doing the database storage, we can do them both at the same time as subtasks on two more threads.We can make this happen merely by instantiating more
ExecutorService
objects. Change theNetworkProcessingAndDatabaseStorage
to instantiate, use, and close an executor service.When run, notice how the elapsed time collapses, going from 6 seconds to 4 seconds. Instead of the network-processing taking 4 seconds followed by the database-storage taking 2 seconds for a total of 6 seconds, they run in parallel on a multi-core machine, for a total of 4 seconds.