无法理解Java线程

时间:2012-02-29 23:22:46

标签: java

我很抱歉,我从python中了解了多处理,我在理解Java的方法时遇到了一些麻烦。在python中,我可以说我想要一个包含4个进程的池,然后将一堆工作发送到我的程序中,它一次只能处理4个项目。我意识到,使用Java,我需要使用线程来实现同样的任务,到目前为止它似乎工作得非常好。

但是..我不像在python中,我的cpu(s)没有获得100%利用率(它们大约70-80%),我怀疑它是我创建线程的方式(python之间的代码是相同的) / java和程序是独立的)。在Java中,我不确定如何创建一个线程,因此我为要处理的列表中的每个项创建一个线程,如下所示:

    for (int i = 0; i < 500; i++) {
        Runnable task = new MyRunnable(10000000L + i);
        Thread worker = new Thread(task);
        // We can set the name of the thread
        worker.setName(String.valueOf(i));
        // Start the thread, never call method run() direct
        worker.start();
        // Remember the thread for later usage
        threads.add(worker);
    }

我是从here拿走的。我的问题是这是启动线程的正确方法,还是有办法让java本身管理线程的数量,以便最佳?我和我想的每个人一样,希望我的代码能够尽快运行,并且我正在努力了解如何分析和解决因创建太多线程而引起的任何问题。这不是一个主要问题,只是对它如何在Java引擎下工作感到好奇。

谢谢!

3 个答案:

答案 0 :(得分:5)

你使用Executor,其实现处理一个线程池,决定多少,等等。有关大量示例,请参阅the Java tutorial

通常,除了非常简单的事情之外,Java中不使用裸线程。相反,会有一些更高级别的API接收您的Runnable或Task并知道该怎么做。

答案 1 :(得分:4)

查看Java Executor API。例如,请参阅此article

尽管创建Threads比以前“便宜”,但是创建大量线程(每个可运行一次,如你的例子中所示)是不可取的 - 创建它们仍然有开销,而你'最终会有太多的上下文切换。

Executor API允许您创建各种类型的线程池来执行Runnable任务,因此您可以重用线程,灵活地管理创建的数量,并避免每个runnable线程的开销。

Java线程模型和Python 线程模型(不是多处理)实际上非常相似。在Python中没有Global Interpreter Lock,因此通常不需要分叉多个进程。

答案 2 :(得分:2)

Thread是一个“低级”API。

根据您要执行的操作以及您使用的Java版本,它们是更好的解决方案。 如果您使用Java 7,并且您的任务允许,您可以使用fork / join框架:http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html

但是,请看一下java并发教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html