限制在java中执行的最大线程数

时间:2013-10-15 16:42:35

标签: java multithreading

试图弄清楚Java中的线程是如何工作的,我只是想通过将它们全部放到数组中来限制可执行线程的执行,然后检查循环中是否有一些完成并弹出它们,以便有可能生成一个新线程,在此代码中出现异常:

public class testThread implements Runnable {
public void run () {
        try {
            Thread.sleep(1000);
        } catch(InterruptedException e){}
        System.out.println("This is the test thread");
    }   

    public static void main (String args[]) {
        int max_threads = 5;
        Thread worker;
        ArrayList<Thread> all_workers = new ArrayList<Thread>(max_threads   );
        for (int i =0; i<50; i++) {
            if (all_workers.size()<max_threads){
                worker = new Thread (new testThread());
                all_workers.add(worker);
                worker.start(); 
            } else{
                System.out.println("i ran all");
                while(all_workers.size()>=max_threads){
                    try{ 
                        System.out.println("Waiting for some to finish");
                        int counter = 0;
                        for (Thread wrk: all_workers){
                            if (!wrk.isAlive()){
                                all_workers.remove(counter);
                            }
                            counter ++ ;
                        }
                        Thread.sleep(500);
                    } catch (InterruptedException e){
                        System.out.println("Catched unhandled ");
                    }
                }
            }
        }

        for(Thread wrk: all_workers){
            try {
                wrk.join();
            } catch (InterruptedException e) {
            }
        }
    }
}
我跑的时候遇到了异常:

anybody@anymachine ~/java $ java testThread 
i ran all
Waiting for some to finish
Waiting for some to finish
This is the test thread
This is the test thread
This is the test thread
This is the test thread
This is the test thread
Waiting for some to finish
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819)
    at java.util.ArrayList$Itr.next(ArrayList.java:791)
    at testThread.main(testThread.java:39)

感谢您的帮助,如果有一个很好的教程,我会非常感兴趣的链接。

PS。如果在Python中有像pdb中的任何调试器请告诉我。 谢谢!

4 个答案:

答案 0 :(得分:7)

您应该查看更高级别的线程实用程序,如ExecutorService和ThreadPools。

你永远不应该手动终止线程,我建议一般不要手动创建/管理线程。

如果要等待多个线程完成,可能需要使用CountDownLatch。 这是an example

答案 1 :(得分:5)

  

线程“main”中的异常java.util.ConcurrentModificationException

您之所以这样,是因为您在迭代它时正从ArrayList中删除。这是不允许的。如果您需要从列表中删除,则应使用iterator.remove()代替:

Iterator<Thread> iterator = all_workers.iterator();
while (interator.hasNext()) {
    if (!interator.next().isAlive()){
        iterator.remove();
    }
}

但真正的答案就像@Thomas说使用ExecutorService代码。那么你要做的是创建一个固定的线程池并将你的工作提交给它:

// create a thread pool with 5 worker threads
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// define your jobs somehow
for (int i = 0; i < 50; i++) {
    threadPool.submit(new testThread());
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
// then wait for it to complete
threadPool.awaitTermination(Long.MAX_LONG, TimeUnit.MILLISECONDS);

答案 2 :(得分:1)

首先,为什么需要限制正在运行的线程数?注意,无论如何,计算机不能同时运行比处理器更多的线程。

您的解决方案的主要缺点是Thread.sleep(500)。这会导致不必要的延迟。

正确的解决方案是使用具有所需线程数的java.util.Executor。然后,您只需拨打executor.execute(new testThread())而不是new Thread (new testThread()).start()

答案 3 :(得分:0)

更改以下行

ArrayList<Thread> all_workers = new ArrayList<Thread>(max_threads);

Set<Thread> all_workers =  Collections.newSetFromMap(new ConcurrentHashMap<Thread,Boolean>())