Visualizzazione dei risultati da 1 a 6 su 6

Discussione: Multithreading

Hybrid View

  1. #1
    Io avrei fatto un piccolo codice di prova che qui posto:

    codice:
    
    package MultiTH;
    
    
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.JProgressBar;
    
    
    public class Interface extends javax.swing.JFrame {
    
    
        /**
         * Creates new form Interface
         */
        public Interface() {
            initComponents();
            this.setVisible(true);
        }
    
    
        /**
         * This method is called from within the constructor to initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is always
         * regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {
    
    
            BarPanel = new javax.swing.JPanel();
            jLabel1 = new javax.swing.JLabel();
            jButton1 = new javax.swing.JButton();
    
    
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    
    
            BarPanel.setBackground(new java.awt.Color(255, 255, 204));
    
    
            jLabel1.setText("jLabel1");
            BarPanel.add(jLabel1);
    
    
            jButton1.setText("OK");
            jButton1.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton1ActionPerformed(evt);
                }
            });
    
    
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(BarPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 327, Short.MAX_VALUE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jButton1)
                    .addContainerGap())
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jButton1)
                            .addGap(0, 0, Short.MAX_VALUE))
                        .addComponent(BarPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE))
                    .addContainerGap())
            );
    
    
            pack();
        }// </editor-fold>                        
    
    
        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
               MultiThreading();
        }                                        
    
    
        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {
            /* Set the Nimbus look and feel */
            //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
            /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
             * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
             */
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (ClassNotFoundException ex) {
                java.util.logging.Logger.getLogger(Interface.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                java.util.logging.Logger.getLogger(Interface.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                java.util.logging.Logger.getLogger(Interface.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(Interface.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>
    
    
            /* Create and display the form */
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new Interface().setVisible(true);
                }
            });
        }
        // Variables declaration - do not modify                     
        private javax.swing.JPanel BarPanel;
        private javax.swing.JButton jButton1;
        private javax.swing.JLabel jLabel1;
        // End of variables declaration                   
    
    
        private void MultiThreading() {
            CalculateA A = new CalculateA();
            CalculateB B = new CalculateB();
            Thread tA = new Thread(A);
            tA.setPriority(10);
            tA.start();
            Thread tB = new Thread(B);
            tB.setPriority(10);
            tB.start();
        }
        
        private class CalculateA implements Runnable{
            @Override
            public void run() {
                JProgressBar A = new JProgressBar();
                A.setMaximum(200);
                BarPanel.add(A);
                BarPanel.revalidate();
                for(int i=0;i<201;i++){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException ex) {}
                    System.out.println("Value A: " + i);
                    synchronized(this){
                        A.setValue(i);
                        A.setString(String.valueOf(i));
                    }
                }
                synchronized(this){
                    BarPanel.remove(A);
                    BarPanel.revalidate();
                    BarPanel.repaint();
                }
            }
            
        }
        private class CalculateB implements Runnable{
            @Override
            public void run() {
                JProgressBar A = new JProgressBar();
                A.setMaximum(500);
                BarPanel.add(A);
                BarPanel.revalidate();
                for(int i=0;i<501;i++){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException ex) {}
    
    
                    System.out.println("Value B: " + i);
                    synchronized(this){
                        A.setValue(i);
                    }
                }
                synchronized(this){
                    BarPanel.remove(A);
                    BarPanel.revalidate();
                    BarPanel.repaint();
                }
    
    
            }
            
        }
    }
    Il codice simula due processi che riempiono due jprogressbar e accedono al thread della GUI tramite synchronized, ho fatto giusto?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Lory1990 Visualizza il messaggio
    Il codice simula due processi che riempiono due jprogressbar e accedono al thread della GUI tramite synchronized, ho fatto giusto?
    No purtroppo. Lo ripeto: l'accesso alla interfaccia utente va fatto "passare" nel EDT (invokeLater/invokeAndWait), non basta un synchronized. Salvo casi, ben documentati e noti, in cui certi metodi della GUI sono "thread-safe". Ma sono davvero pochi.

    Inoltre sempre nei tuoi Runnable hai creato il JProgressBar. Idem è sbagliato, va fatto nel EDT.

    E ancora, hai usato synchronized(this) che di per sé è tecnicamente corretto ma non è appropriato. Se vuoi che un thread A possa modificare uno "stato" di qualcosa in modo che poi un thread B possa leggerlo correttamente, devi sì usare la sincronizzazione (se non è già implicita es. in qualche struttura dati) ma sopratutto sia A che B devono usare lo stesso oggetto di lock.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.