一个Java虚拟机可以支持多少线程?这因供应商而异吗?按操作系统?其他因素?


当前回答

2017年…… DieLikeADog类。

新线程#92459 java.lang.OutOfMemoryError:无法创建新的本机线程

i7 - 7700 16 gb的ram

其他回答

你可以处理任意数量的线程;没有限制。我在看电影和使用NetBeans时运行了下面的代码,它正常工作/没有停止机器。我认为你可以保留比这个程序更多的线程。

class A extends Thread {
    public void run() {
        System.out.println("**************started***************");
        for(double i = 0.0; i < 500000000000000000.0; i++) {
            System.gc();
            System.out.println(Thread.currentThread().getName());
        }
        System.out.println("************************finished********************************");
    }
}

public class Manager {
    public static void main(String[] args) {
        for(double j = 0.0; j < 50000000000.0; j++) {
            A a = new A();
            a.start();
        }
    }
}

在摆弄了Charlie的dielikecode类之后,Java线程堆栈大小似乎是您可以创建的线程数量的很大一部分。

设置java线程堆栈大小

例如

java -Xss100k DieLikeADog

但是,Java有Executor接口。我会使用它,你将能够提交数千个可运行的任务,并让Executor处理这些任务与固定数量的线程。

嗯,很多。

这里有几个参数。特定的VM,加上VM上通常还有运行时参数。这在某种程度上是由操作系统驱动的:底层操作系统对线程有什么支持,它对线程有什么限制?如果虚拟机实际上使用操作系统级别的线程,那就是红色线程/绿色线程。

“支持”是另一个问题。如果你写一个Java程序,就像

   class DieLikeADog {
         public static void main(String[] argv){
             for(;;){
                new Thread(new SomeRunaable).start();
             }
         }
    }

(不要抱怨语法细节,这是我第一次喝咖啡),那么您肯定会有数百或数千个线程在运行。但是创建一个线程是相对昂贵的,调度器开销可能会变得紧张;不清楚是否可以让这些线程做任何有用的事情。

更新

好吧,忍不住了。下面是我的小测试程序,做了一些修饰:

public class DieLikeADog {
    private static Object s = new Object();
    private static int count = 0;
    public static void main(String[] argv){
        for(;;){
            new Thread(new Runnable(){
                    public void run(){
                        synchronized(s){
                            count += 1;
                            System.err.println("New thread #"+count);
                        }
                        for(;;){
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e){
                                System.err.println(e);
                            }
                        }
                    }
                }).start();
        }
    }
}

在英特尔的OS/X 10.5.6和Java 6 5(见评论)上,这是我得到的

New thread #2547
New thread #2548
New thread #2549
Can't create thread: 5
New thread #2550
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:592)
        at DieLikeADog.main(DieLikeADog.java:6)

最大线程数取决于以下因素: 硬件配置,如微处理器,RAM。 操作系统是32位还是64位 run方法内部的代码。如果run方法内的代码很大,那么单个线程对象将有更多的内存需求

理论上的绝对最大值通常是进程的用户地址空间除以线程堆栈大小(尽管在现实中,如果所有的内存都留给线程堆栈,那么程序就无法正常工作……)

例如,在32位Windows下,每个进程的用户地址空间为2GB,给每个线程128K的堆栈大小,您期望的绝对最大值为16384个线程(=2*1024*1024 / 128)。在实践中,我发现在XP下我可以启动大约13,000。

然后,我认为你本质上是(a)你是否可以在你的代码中管理这么多线程,而不是做明显的愚蠢的事情(比如让它们都等待同一个对象,然后调用notifyAll()…),以及(b)操作系统是否可以。原则上,如果(a)的答案也是“是”,那么(b)的答案就是“是”。

顺便说一句,你可以在Thread的构造函数中指定堆栈大小;你不需要(可能也不应该)为此而打乱VM参数。