2

试图弄清楚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。如果在 java 中有任何调试器,例如 python 中的 pdb,请告诉我。谢谢你!

4

4 回答 4

7

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

您永远不应该手动终止线程,我建议通常避免手动创建/管理线程。

如果您想等待多个线程完成,您可能需要使用 CountDownLatch。这是一个例子

于 2013-10-15T16:49:10.107 回答
6

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

你得到这个是因为你正在从ArrayList你迭代它的时候移除。这是不允许的。

for (Thread wrk : all_workers) {
   if (!wrk.isAlive()) {
      // ERROR, you can't change the collection while you are in a for loop
      all_workers.remove(counter);
   }
   ...

如果您需要从您正在走过的列表中删除,您应该iterator.remove()改用:

Iterator<Thread> iterator = all_workers.iterator();
while (interator.hasNext()) {
    Thread wrk = interator.next();
    if (!wrk.isAlive()) {
        // this is allowed because you are using the iterator directly
        iterator.remove();
    }
}

针对您的具体情况的更好解决方案是使用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);
于 2013-10-15T17:11:01.670 回答
1

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

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

正确的解决方案是使用java.util.Executor所需数量的线程。然后你只需调用executor.execute(new testThread())而不是new Thread (new testThread()).start().

于 2013-10-15T17:33:10.123 回答
0

更改以下行

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

Set<Thread> all_workers =  Collections.newSetFromMap(new ConcurrentHashMap<Thread,Boolean>())
于 2013-10-15T17:02:43.670 回答