根据标题,看看这段代码:
Thread outer = new Thread(new Runnable() {
@Override
public void run() {
Thread inner1 = new Thread(new Runnable() {
@Override
public void run() {
//some statements and other inner threads
}
});
Thread inner2 = new Thread(new Runnable() {
@Override
public void run() {
//some statements and other inner threads
}
});
//some statements and other inner threads
}
});
那么,使用这样的多线程是一个好习惯吗?
此致
答案 0 :(得分:2)
任何编程语言都没有内部线程。线程只是具有sort -n $pngTotal $gifTotal
方法的对象,其特点是多个线程可以同时运行(并发)。
在您的示例中,您在Thread的run()
方法中创建了两个Threads。这不是问题,因为您可以在任何上下文中创建对象。
如果你想使用线程,你必须在创建线程后调用run()
,outer.start()
和inner1.start()
,否则它们不会被执行。再一次,这绝对没问题,因为在线程启动的上下文中并不重要;所有线程都由Java虚拟机平等对待。
答案 1 :(得分:1)
根据Q1“它是好的”。这是正确的,但创建威胁只是为了创建另一个线程没有多大意义。
另外,请记住,创建Thread对象是相对昂贵的操作。
您的代码中有//some statements and other inner threads
条评论。考虑使用ThreadPoolExecutor来避免手动创建多个线程。
答案 2 :(得分:1)
这篇关于并发性的Java Code Geeks文章为您提供了一些建议。我建议你完整阅读它,但这里有两个重要的片段:
通常,不建议使用Thread类的实例直接创建和管理线程...
和此:
在Java中创建新线程很简单,但管理它们确实很简单 强硬。 Java标准库提供了非常有用的抽象 用于简化线程的执行程序和线程池的形式 管理。
基本上,在最简单的实现中,线程池创建和 维护一个线程列表,随时可以使用。 应用程序,而不是每次产生新的线程,只是借用 池中的一个(或多个需要的)。一旦借来的线程 完成它的工作,它返回到池中,并成为 可以接受下一个任务。
虽然可以直接使用线程池,但Java标准 library提供了一个executorsfaçade,它有一套工厂方法 创建常用的线程池配置。
线程有很多要管理的状态,这也在文章中指出:
以下是this question的答案中的其他注意事项:
是的,您可以根据需要启动任意数量的线程,但这可能是 不是最好的方式。使用非阻塞API会好得多 这样你就可以开始执行一些外部呼叫和呼叫了 线程可以立即开始做其他事情而无需等待 socket / database调用回来。然后,当socket /数据库 呼叫返回,触发回调以完成处理。
非阻塞I / O可以提供更高的CPU利用率,因为您 只是触发调用和注册回调而不必尝试 平衡大多数并发线程的“正确”数量 只是睡觉了。
层次结构是否重要?
使用带有缓存的ExecutorService可能会更好 线程池。
这样你就可以汇集线程而不是创建批量(这是 昂贵)。 ExecutorServices还提供其他很酷的东西,并使用 使用Callables / Runnables可能比测试更容易 用你自己的线程来捣乱。
答案 3 :(得分:1)
我不喜欢这种方式,因为:
*不太可读
*除非你手动设置
,否则线程2会自动选择线程1优先级*线程调度程序基于JVM(如时间片,排队......)所以你不知道线程1何时会通过可运行状态
*如果线程2依赖于线程1,您可以使用wait和notify或其他新功能来实现此目标,以便它更具可读性