ไม่ Java Swing คอมโพเนนต์ไม่ปลอดภัยต่อเธรดใน Java
เหตุใด Swing Components จึงไม่ปลอดภัยสำหรับเธรด
- สาเหตุหลักประการหนึ่งสำหรับ Java Swing ที่ไม่ปลอดภัยสำหรับเธรดคือการทำให้งานในการขยายคอมโพเนนต์ง่ายขึ้น
- อีกเหตุผลหนึ่งสำหรับ Java Swing นั้นไม่ปลอดภัยสำหรับเธรดเนื่องจากมีค่าใช้จ่ายที่เกี่ยวข้องกับ การรับและปล่อยการล็อกและการกู้คืนสถานะ .
- เมธอดของคอมโพเนนต์ Java Swing บางส่วนจะสนับสนุนการเข้าถึงแบบมัลติเธรด เช่น repaint(), revalidate() และ ทำให้วิธีการ () ใช้ไม่ได้ ของ JComponent คลาส.
กระทู้ส่งกิจกรรม (EDT)
คอมโพเนนต์ Java Swing สามารถเข้าถึงได้จาก Event Dispatch Thread (EDT .) เท่านั้น ) เมื่อส่วนประกอบพร้อมสำหรับการวาดภาพบนหน้าจอ EDT กระทู้ เป็นเธรดที่เรียกใช้วิธีการโทรกลับเช่น paint() และ update() นอกเหนือจากวิธีการจัดการเหตุการณ์ที่กำหนดไว้ใน ตัวฟังเหตุการณ์ i อินเทอร์เฟซ เฉพาะเมธอดเธรดที่ปลอดภัยเท่านั้นที่สามารถเรียกใช้จากเธรดใดๆ ได้อย่างปลอดภัย เนื่องจากเมธอด Swing ส่วนใหญ่ไม่ปลอดภัยสำหรับเธรด จึงสามารถเรียกใช้จากเธรดเดียว EDT .
ตัวอย่าง
import javax.swing.*; import java.awt.Dimension; import java.awt.event.*; public class EDTTest extends JPanel implements ActionListener { private static EDTTest myPanel; private static JFrame myFrame; public EDTTest() { super(); } public Dimension getPreferredSize() { return new Dimension(500,425); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } private static void createAndShowGUI() { myFrame = new JFrame("EDT Program"); myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); myFrame.setLocationRelativeTo(null); myPanel = new EDTTest(); myFrame.add(myPanel); initMenu(); myFrame.setVisible(true); } private static void initMenu() { JMenuBar menuBar = new JMenuBar(); myFrame.setJMenuBar(menuBar); JMenu file = new JMenu("File"); JMenuItem quit = new JMenuItem("Quit"); quit.addActionListener(myPanel); file.add(quit); menuBar.add(file); } public void actionPerformed(ActionEvent ae) { String choice = ae.getActionCommand(); if (choice.equals("Quit")) { System.exit(0); } } }
ในตัวอย่างข้างต้น SwingUtilities.invokeLater() เมธอดจะหน่วงเวลางานสร้าง GUI จนกว่างานของเธรดเริ่มต้นจะเสร็จสิ้น จากนั้นตรวจสอบให้แน่ใจว่าการสร้าง GUI เกิดขึ้นภายใน EDT
ผลลัพธ์