同时创建动态线程数
Posted
技术标签:
【中文标题】同时创建动态线程数【英文标题】:Creating dynamic number of threads concurrently 【发布时间】:2012-04-22 22:48:08 【问题描述】:每次我必须创建可变数量的线程。 我通过创建一个线程数组并创建多个线程来做到这一点。
但是,我不明白如何启动这 n 个线程,其行为类似于多线程概念。 我希望它们并行运行。
如果在这个场景中做什么,请指导。
【问题讨论】:
【参考方案1】:但是,我不明白如何启动这 n 个线程,其行为类似于多线程概念。我希望它们并行运行。
您当然可以使用循环创建线程数组:
Thread[] threads = new Thread[NUM_JOBS_TO_CREATE];
for (int i = 0; i < threads.length; i++)
threads[i] = new Thread(new Runnable()
public void run()
// some code to run in parallel
// this could also be another class that implements Runnable
);
threads[i].start();
这将导致线程在后台并行运行。然后,您可以稍后加入他们,等待他们全部完成后再继续。
// wait for the threads running in the background to finish
for (Thread thread : threads)
thread.join();
但我建议不要自己管理线程,而是使用内置的Java Executors
。他们做这一切是因为你更容易管理。这种方法的好处之一是它将 tasks 与运行它们的 threads 分开。例如,您可以启动 10 个线程来并行运行 1000 个和 1000 个任务。
这里有一些示例 ExecutorService
代码:
// create a pool of threads, 10 max jobs will execute in parallel
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// submit jobs to be executing by the pool
for (int i = 0; i < NUM_JOBS_TO_CREATE; i++)
threadPool.submit(new Runnable()
public void run()
// some code to run in parallel
// this could also be another class that implements Runnable
);
// once you've submitted your last job to the service it should be shut down
threadPool.shutdown();
// wait for the threads to finish if necessary
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
有关详细信息,请参阅Java tutorial on the thread executors。
【讨论】:
如果我有 1000 个作业,它将创建 1000 个对象,这会导致性能问题 1000 个对象非常便宜@ManojRamanan。从对象带宽的角度来看,1000 个字符串更昂贵。如果您创建了一百万个对象,您可能会注意到一些 GC 问题,因此我们通常在队列上设置边界,以防Runnable
生产者比消费者快得多。
感谢@Gray 提供的信息。您能否分享一些我目前正在使用此实现的信息。您如何测试它【参考方案2】:
尽量不要创建线程数组并尝试管理它们 - 它很快就会变成令人震惊的混乱。如果你需要一个线程池来运行任务,你需要一个生产者-消费者队列。创建一个并在创建线程时将其(或包含它作为成员的线程池对象实例)传递给线程。线程循环,获取任务并执行它们。
执行此操作的简单方法是使用@Gray (+1) 详述的 ExecutorService。
为了强调,我再说一遍,不要试图对数组、列表或向量中的线程进行微观管理、启动它们、在“老板/管理”循环中检查它们的状态、终止/中止它们、销毁它们等。等等。就像保时捷 911 - 在花费大量金钱/时间来获得一辆之后,你会得到一些似乎可以正常工作的东西,然后它会突然破碎并将你旋转成一棵树。
为长时间阻塞的作业使用专用线程,为那些可以集中快速完成的作业使用线程池。
【讨论】:
【参考方案3】:基本伪代码:
create x threads, store them in an array or list;
for each thread in the list/array
call start() on the thread object;
【讨论】:
如果我这样做,线程不会并行运行。但是,它们作为普通函数调用按顺序运行 @sowmya 我认为您需要阅读线程。在一堆线程上按顺序调用 start() 并不意味着它们是按顺序运行的,它只是意味着它们是按顺序启动的。 但是,它们是按照我启动它们的顺序依次执行的。据我所知,至少输出应该改变。但是,它没有发生。如果我错了,请纠正我。 它们各自执行各自版本的函数。【参考方案4】:在一个需要多线程的类中我设置在类的顶部:
private static final ExecutorService executor = Executors.newCachedThreadPool();
& 在 Java 8+ 中,只要我需要在新线程中运行一些东西,就使用 lamda 表达式:
executor.submit(() ->
myOtherClass.myFunction(doSomething);
);
使用newCachedThreadPool
,Java 将根据系统上的 cpu 核心数管理线程总数,并在一段时间不活动后自动停止它们(默认为60
秒)。
【讨论】:
【参考方案5】:Scanner reader = new Scanner(System.in);
System.out.println("Enter a positive number: ");
int n = reader.nextInt();
if(n>0)
Thread[] ob = new Thread[n];
for (int i = 0; i < ob.length; i++)
int num = i+1;
ob[i] = new Thread(new Runnable()
public void run()
System.out.println("Hello, I am Thread #"+num);
);
ob[i].start();
else
System.out.println("Please Enter A Positive Integer");
【讨论】:
欢迎来到 Stack Overflow。虽然这很可能是解决 OP 问题的代码,但请对代码的作用以及它回答问题的原因添加一些解释。以上是关于同时创建动态线程数的主要内容,如果未能解决你的问题,请参考以下文章