McGoverntheory ถามคำถามนี้ใน Stackoverflow:
Java Virtual Machine รองรับกระทู้ได้กี่เธรดมากที่สุด? เกี่ยวข้องกับนักพัฒนาเครื่องเสมือนจริงหรือไม่? แล้วระบบปฏิบัติการล่ะ? มีปัจจัยอื่น ๆ อีกไหม?
คำตอบของ Eddie:
ขึ้นอยู่กับ CPU ที่คุณใช้ระบบปฏิบัติการกระบวนการอื่น ๆ กำลังทำอะไรรุ่นของ Java ที่คุณใช้และปัจจัยอื่น ๆ ฉันเคยเห็นเซิร์ฟเวอร์ Windows ที่มีมากกว่า 6500 เธรดก่อนที่มันจะลง แน่นอนกระทู้ส่วนใหญ่ไม่ทำอะไรเลย เมื่อมีเธรดเกือบ 6500 (ใน Java) บนเครื่องแล้วเครื่องจะเริ่มมีปัญหาและไม่เสถียร
จากประสบการณ์ของฉันเธรดที่มีอยู่ใน JVM มีความสัมพันธ์เชิงบวกกับประสิทธิภาพของคอมพิวเตอร์เอง
แน่นอนคุณต้องมีหน่วยความจำดั้งเดิมเพียงพอและจัดสรรหน่วยความจำให้เพียงพอให้กับ Java เพื่อให้แต่ละเธรดสามารถมีสแต็ก (สแต็คเครื่องเสมือน) และสามารถทำสิ่งที่คุณต้องการได้ เครื่องใด ๆ ที่มี CPU ที่ทันสมัย (AMD หรือ Intel รุ่นล่าสุด) และหน่วยความจำ 1-2G (ขึ้นอยู่กับระบบปฏิบัติการ) สามารถรองรับเครื่องเสมือน Java ที่มีเธรดนับพันได้อย่างง่ายดาย
หากคุณต้องการคำตอบที่แม่นยำยิ่งขึ้นคุณควรทดสอบความเครียดด้วยตัวเอง
คำตอบของ Charlie Martin:
มีพารามิเตอร์มากมาย (สามารถตั้งค่าได้) สำหรับเครื่องเสมือนที่เฉพาะเจาะจงพวกเขาจะมีพารามิเตอร์รันไทม์ของตัวเอง (จำนวนเธรดสูงสุด) ในระดับหนึ่งมันถูกกำหนดโดยระบบปฏิบัติการ: ระบบปฏิบัติการพื้นฐานควรให้การสนับสนุนอะไรกับเธรด? มีข้อ จำกัด อะไรบ้าง? เครื่องเสมือนใช้เธรดของระบบปฏิบัติการดั้งเดิมหรือเธรดสีแดงหรือเธรดสีเขียวหรือไม่?
การสนับสนุนที่จัดทำโดยระบบปฏิบัติการเป็นอีกปัญหาหนึ่ง หากคุณเขียนโปรแกรม Java เช่นนี้:
การคัดลอกรหัสมีดังนี้:
คลาส dielikeadog {
โมฆะคงที่สาธารณะหลัก (สตริง [] argv) {
สำหรับ(;;){
เธรดใหม่ (ใหม่ somerunaable). start ();
-
-
-
(อย่าบ่นเกี่ยวกับรายละเอียดทางไวยากรณ์นี่เป็นเพียงการเริ่มต้น) แน่นอนว่าคุณต้องการรับเธรดที่ใช้งานได้หลายร้อยรายการ อย่างไรก็ตามค่าใช้จ่ายในการสร้างเธรดค่อนข้างสูงและค่าใช้จ่ายของการกำหนดเวลา (มากเกินไป) จะโดดเด่น ยังคงไม่แน่ใจว่าเธรดเหล่านี้สามารถทำสิ่งที่เป็นประโยชน์ได้หรือไม่
เวอร์ชันอัพเกรด
โอเครอไม่ไหวแล้ว! นี่คือโปรแกรมทดสอบขนาดเล็กที่ได้รับการขัดเล็กน้อย:
คัดลอกรหัสดังต่อไปนี้: คลาสสาธารณะ dielikeadog {
วัตถุคงที่ส่วนตัว s = วัตถุใหม่ ();
จำนวน int คงที่ส่วนตัว = 0;
โมฆะคงที่สาธารณะหลัก (สตริง [] argv) {
สำหรับ(;;){
เธรดใหม่ (ใหม่ runnable () {
โมฆะสาธารณะเรียกใช้ () {
ซิงโครไนซ์ {
นับ += 1;
System.err.println ("เธรดใหม่ #"+นับ);
-
สำหรับ(;;){
พยายาม {
Thread.sleep (1,000);
} catch (Exception e) {
System.err.println (e);
-
-
-
}).เริ่ม();
-
-
-
ในระบบ OS/X 10.5.6 ของ Intel เอาต์พุตของ Java 5 มีดังนี้:
การคัดลอกรหัสมีดังนี้:
กระทู้ใหม่ #2547
กระทู้ใหม่ #2548
กระทู้ใหม่ #2549
ไม่สามารถสร้างเธรด: 5
กระทู้ใหม่ #25550
ข้อยกเว้นในเธรด "หลัก" java.lang.outofmemoryError: ไม่สามารถสร้างเธรดเนทีฟใหม่
ที่ java.lang.thread.start0 (วิธีการดั้งเดิม)
ที่ java.lang.thread.start (thread.java:592)
ที่ dielikeadog.main (dielikeadog.java:6)
คำตอบของ Benjismith:
หลังจากอ่านคำตอบของ Charlie Martin ฉันสงสัยว่าขนาดของหน่วยความจำฮีปสามารถสร้างความแตกต่างในจำนวนเธรดที่สร้างขึ้นและจากนั้นฉันก็ตกตะลึงกับผลลัพธ์: ในระบบ Vista Home Premium SP1 โดยใช้ JDK 1.6.0_11 ตั้งค่าขนาดของหน่วยความจำฮีปจาก 2m เป็น 1024m เพื่อดำเนินการโปรแกรมทดสอบของ Charlie ตัวอย่างเช่น: ในการสร้างหน่วยความจำ 2M HEAP พารามิเตอร์เครื่องเสมือนที่ฉันใช้คือ: -XMS2M -XMX2M
นี่คือผลการทดสอบของฉัน:
คัดลอกรหัสดังต่อไปนี้: 2 MB -> 5744 เธรด
4 MB -> 5743 เธรด
8 MB -> 5735 เธรด
12 MB -> 5724 เธรด
16 MB -> 5712 เธรด
24 MB -> 5687 เธรด
32 MB -> 5662 เธรด
48 MB -> 5610 เธรด
64 MB -> 5561 เธรด
96 MB -> 5457 เธรด
128 MB -> 5357 เธรด
192 MB -> 5190 เธรด
256 MB -> 5014 เธรด
384 MB -> 4606 เธรด
512 MB -> 4202 เธรด
768 MB -> 3388 เธรด
1024 MB -> 2583 เธรด
ดังนั้นขนาดของกองจึงสำคัญมาก อย่างไรก็ตามขนาดฮีปและจำนวนเธรดสูงสุดนั้นมีสัดส่วนผกผัน
มันแปลกมาก!
คำตอบของ Neil Coffey:
จำนวนเธรดสูงสุดทางทฤษฎีที่แน่นอนคือพื้นที่ที่อยู่ผู้ใช้ของกระบวนการหารด้วยขนาดของสแต็กเธรด (ในความเป็นจริงหากหน่วยความจำทั้งหมดถูกใช้โดยสแต็กเธรดจะไม่มีโปรแกรมที่สามารถเรียกใช้ได้) ดังนั้นการใช้ระบบ Windows 32 บิตเป็นตัวอย่างพื้นที่ที่อยู่ผู้ใช้ของแต่ละกระบวนการคือ 2G . ที่จริงแล้วในระบบ XP ฉันพบว่าสามารถเริ่มต้นได้ประมาณ 13,000 เธรด
จากนั้นฉันคิดว่าคำถามของคุณเป็นหลัก: (a) ไม่ว่าคุณจะสามารถจัดการเธรดจำนวนมากได้อย่างมีประสิทธิภาพในรหัสของคุณ จัดการเธรดจำนวนมากเหล่านี้ได้อย่างมีประสิทธิภาพ โดยทั่วไปถ้าคำตอบของ (A) คือ "ใช่" คำตอบของคำตอบ (B) คือ "ใช่"
โดยบังเอิญคุณสามารถตั้งค่าขนาดสแต็กเธรดในตัวสร้างเธรด แต่คุณไม่จำเป็นต้องและไม่ควรสับสนกับพารามิเตอร์เครื่องเสมือน