เธรดแพลตฟอร์มเทียบกับเธรดเสมือน
เลือกใช้แต่ละแบบเมื่อใด
เธรดแพลตฟอร์มเทียบกับเธรดเสมือน เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
เธรดสองประเภท
ปัจจุบัน Java มีเธรดอยู่สองรูปแบบ เธรดแพลตฟอร์มเป็นตัวห่อหุ้มแบบดั้งเดิมรอบเธรดของ OS ส่วนเธรดเสมือนมีน้ำหนักเบาและจัดการโดย JVM
การรู้ว่าควรเลือกใช้แต่ละแบบเมื่อใดคือหัวใจของการเขียน Java ที่ทำงานพร้อมกันและรองรับการขยายได้
การสร้างเธรดแพลตฟอร์ม
คุณสร้างเธรดแพลตฟอร์มด้วย Thread.ofPlatform() ซึ่งเป็นคู่เทียบของ Thread.ofVirtual()
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread p = Thread.ofPlatform().name("native-worker").start(() ->
System.out.println("Platform? " + !Thread.currentThread().isVirtual()));
p.join();
}
}การเปรียบเทียบต้นทุน
เธรดแพลตฟอร์มใช้ทรัพยากรมาก:
- จองหน่วยความจำกองซ้อนประมาณ 1 MB ต่อเธรด
- สร้างได้ช้า
- รองรับได้เพียงไม่กี่พันเธรด
เธรดเสมือนใช้ทรัพยากรน้อย: ใช้กองซ้อนเริ่มต้นขนาดเล็ก สร้างได้รวดเร็ว และสามารถสร้างได้หลายล้านเธรด
งานที่ผูกกับการรับส่งข้อมูล
หากงานของคุณใช้เวลาส่วนใหญ่ไปกับการรอเครือข่าย ดิสก์ หรือฐานข้อมูล เธรดเสมือนจะให้ประโยชน์อย่างมาก
ขณะที่เธรดเสมือนหนึ่งเธรดกำลังรอแบบขัดขวาง เธรดพาหะของมันจะถูกปล่อยให้ไปทำงานอื่นได้ ดังนั้นเธรดของ OS เพียงไม่กี่เธรดจึงรองรับคำขอได้หลายพันรายการ
งานที่ผูกกับการคำนวณของ CPU
สำหรับการคำนวณล้วน ๆ ที่ไม่เคยหยุดรอ เธรดเสมือนไม่ได้เพิ่มความเร็ว คุณยังคงถูกจำกัดด้วยจำนวนแกนประมวลผล
ในกรณีนี้ กลุ่มเธรดคงที่ที่มีขนาดตามจำนวนตัวประมวลผลคือเครื่องมือที่เหมาะสม
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws Exception {
int cores = Runtime.getRuntime().availableProcessors();
try (ExecutorService cpu = Executors.newFixedThreadPool(cores)) {
Future<Long> f = cpu.submit(() -> {
long s = 0;
for (long i = 0; i < 1_000_000L; i++) s += i;
return s;
});
System.out.println("Cores: " + cores + ", sum: " + f.get());
}
}
}การจำลองการรอแบบขัดขวาง
ส่วนย่อยนี้แสดงเธรดเสมือนจำนวนมากที่หยุดพัก (เพื่อใช้แทนการรับส่งข้อมูลแบบรอ) พร้อมกัน ลองจินตนาการว่ามีเธรดแพลตฟอร์ม 10,000 เธรดทำสิ่งเดียวกัน
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) {
AtomicInteger done = new AtomicInteger();
try (ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10_000; i++) {
exec.submit(() -> {
try { Thread.sleep(50); } catch (InterruptedException e) {}
done.incrementAndGet();
});
}
}
System.out.println("Finished blocking tasks: " + done.get());
}
}สถานะดีมอน
เธรดเสมือนเป็นเธรดดีมอนเสมอและไม่สามารถเปลี่ยนให้เป็นเธรดที่ไม่ใช่ดีมอนได้ เธรดแพลตฟอร์มจะสืบทอดสถานะดีมอนของผู้สร้างโดยค่าเริ่มต้น แต่สามารถกำหนดสถานะได้โดยชัดแจ้ง
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread v = Thread.ofVirtual().unstarted(() -> {});
Thread p = Thread.ofPlatform().unstarted(() -> {});
System.out.println("virtual daemon: " + v.isDaemon());
System.out.println("platform daemon: " + p.isDaemon());
}
}ไม่สนใจลำดับความสำคัญ
เธรดเสมือนจะรายงานลำดับความสำคัญเป็น NORM_PRIORITY เสมอ และการกำหนดลำดับความสำคัญจะไม่มีผล การจัดตารางการทำงานดำเนินการโดย JVM ไม่ใช่ตัวจัดตารางของ OS
public class Main {
public static void main(String[] args) {
Thread v = Thread.ofVirtual().unstarted(() -> {});
v.setPriority(Thread.MAX_PRIORITY);
System.out.println("Priority is still: " + v.getPriority());
}
}แนวทางการตัดสินใจ
หลักง่าย ๆ ที่ใช้ได้จริง:
- มีงานจำนวนมากที่รอการรับส่งข้อมูลหรือไม่ ใช้เธรดเสมือน
- มีการคำนวณหนักที่ถูกจำกัดด้วย CPU หรือไม่ ใช้กลุ่มเธรดแพลตฟอร์มคงที่
- ต้องปรับแต่งเธรดในระดับ OS เช่น ลำดับความสำคัญหรือความผูกติดกับหน่วยประมวลผลหรือไม่ ใช้เธรดแพลตฟอร์ม
ทำงานร่วมกันได้
คุณไม่จำเป็นต้องเลือกเพียงแบบเดียวสำหรับทั้งโปรแกรม แอปทั่วไปใช้เธรดเสมือนจัดการคำขอ และใช้กลุ่มเธรดแพลตฟอร์มขนาดเล็กสำหรับส่วนที่ใช้ CPU หนัก
ทั้งสองแบบใช้ส่วนติดต่อเดียวกับ Thread ดังนั้นการใช้งานร่วมกันจึงราบรื่น
เคล็ดลับการย้ายระบบ
เมื่อย้ายบริการที่ใช้การรับส่งข้อมูลอย่างหนัก การเปลี่ยนแปลงที่น้อยที่สุดคือการสลับตัวจัดการงาน: แทนที่กลุ่มเธรดคงที่หรือกลุ่มเธรดแบบเก็บไว้ใช้ซ้ำด้วย newVirtualThreadPerTaskExecutor()
โปรดระวังการตรึงเธรดและการใช้ ThreadLocal มากเกินไป ซึ่งจะกล่าวถึงในบทเรียนถัดไป
ตรวจสอบความเข้าใจอย่างรวดเร็ว
เลือกภาระงานที่เธรดเสมือนให้ประโยชน์อย่างชัดเจนที่สุด
สรุป
คุณได้เปรียบเทียบรูปแบบเธรดทั้งสองแบบแล้ว:
- เธรดแพลตฟอร์ม: ใช้ทรัพยากรมาก ทำงานบน OS เหมาะที่สุดกับงานที่ผูกกับ CPU และการปรับแต่งระดับ OS
- เธรดเสมือน: ใช้ทรัพยากรน้อย จัดการโดย JVM เป็นดีมอนเสมอ และเหมาะที่สุดกับการทำงานพร้อมกันที่ผูกกับการรับส่งข้อมูล
- ทั้งสองแบบทำงานร่วมกันได้และใช้ส่วนติดต่อเดียวกัน
ถัดไป: ข้อควรระวังเรื่องการตรึงเธรดและ ThreadLocals
คำถามที่พบบ่อย
บทเรียน “เธรดแพลตฟอร์มเทียบกับเธรดเสมือน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “เธรดแพลตฟอร์มเทียบกับเธรดเสมือน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “เธรดแพลตฟอร์มเทียบกับเธรดเสมือน”
เลือกใช้แต่ละแบบเมื่อใด คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “เธรดแพลตฟอร์มเทียบกับเธรดเสมือน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม
ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เธรดเสมือนคืออะไร
- การสร้างเธรดเสมือน
- เธรดแพลตฟอร์มเทียบกับเธรดเสมือน
- ข้อควรระวัง: การตรึงและ ThreadLocals