Imansible ottenere ArrayIndexOutOfBoundsException da Future E SwingWorker se il thread avvia Executor

Gioco con il multitreading per SwingWorker usando Executor, e sono lì per errore identificato elementi errati dal vettore, sembra che questo codice ignori piuttosto che l’elemento in Vector non esiste

la mia domanda -> come / è ansible prendere questa o quelle eccezioni in qualche modo

uscita semplice

run: Thread Status with Name :StartShedule, SwingWorker Status is STARTED Thread Status with Name :StartShedule, SwingWorker Status is DONE Thread Status with Name :StartShedule, SwingWorker Status is STARTED Thread Status with Name :StartShedule, SwingWorker Status is DONE Thread Status with Name :StartShedule, SwingWorker Status is STARTED Thread Status with Name :StartShedule, SwingWorker Status is DONE BUILD SUCCESSFUL (total time: 11 seconds) 

per disapprovazione

 //changeTableValues1(); // un-comment for get ArrayIndexOutOfBoundsException 

tutto è corretto, ricevo ArrayIndexOutOfBoundsException e l’output è

 run: Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 2 at java.util.Vector.get(Vector.java:694) at KondorExport.Util.Help.Table.TableWithExecutor.changeTableValues1(TableWithExecutor.java:70) at KondorExport.Util.Help.Table.TableWithExecutor.access$100(TableWithExecutor.java:18) at KondorExport.Util.Help.Table.TableWithExecutor$2.actionPerformsd(TableWithExecutor.java:61) at javax.swing.Timer.fireActionPerformsd(Timer.java:271) at javax.swing.Timer$DoPostEvent.run(Timer.java:201) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Thread Status with Name :StartShedule, SwingWorker Status is STARTED Thread Status with Name :StartShedule, SwingWorker Status is DONE BUILD SUCCESSFUL (total time: 10 seconds) 

dal codice

 import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; import java.util.Vector; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import javax.swing.*; import javax.swing.table.*; public class TableWithExecutor extends JFrame { private static final long serialVersionUID = 1L; private String[] columnNames = {"Narrative", "Description"}; private Object[][] data = {{"About", "About"}, {"Add", "Add"}}; private JTable table; private Executor executor = Executors.newCachedThreadPool(); private Timer timerRun; private int delay = 3000; private Vector fwDeals; private Vector fwDeals1; public TableWithExecutor() { DefaultTableModel model = new DefaultTableModel(data, columnNames); table = new JTable(model) { private static final long serialVersionUID = 1L; @Override public Class getColumnClass(int column) { return getValueAt(0, column).getClass(); } }; table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane, BorderLayout.CENTER); prepareStartShedule(); } private void prepareStartShedule() { timerRun = new javax.swing.Timer(delay, startCycle()); timerRun.setRepeats(true); timerRun.start(); } private Action startCycle() { return new AbstractAction("Start Shedule") { private static final long serialVersionUID = 1L; @Override public void actionPerformsd(ActionEvent e) { executor.execute(new TableWithExecutor.MyTask("StartShedule")); //non on EDT //changeTableValues1(); // un-comment for get ArrayIndexOutOfBoundsException } }; } private void changeTableValues1() { fwDeals1 = new Vector(); fwDeals1.add("First"); // ElementAt(0) fwDeals1.add("Second");// ElementAt(1) checkDealsInDb1(fwDeals1.get(1), fwDeals1.get(2)); } private void checkDealsInDb1(String Str, String Str1) { table.getModel().setValueAt(Str, 0, 1); table.getModel().setValueAt(Str1, 1, 1); } private void changeTableValues() { fwDeals = new Vector(); fwDeals.add("First"); // ElementAt(0) fwDeals.add("Second");// ElementAt(1) checkDealsInDb(fwDeals.get(1), fwDeals.get(2)); } private void checkDealsInDb(String Str, String Str1) { table.getModel().setValueAt(Str, 0, 1); table.getModel().setValueAt(Str1, 1, 1); } public static void main(String[] args) { TableWithExecutor frame = new TableWithExecutor(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.setLocation(150, 150); frame.pack(); frame.setVisible(true); } private class MyTask extends SwingWorker { private String str; private String namePr; MyTask(String str) { this.str = str; addPropertyChangeListener(new SwingWorkerCompletionWaiter(str, namePr)); } @Override protected Void doInBackground() throws Exception { if (str.equals("StartShedule")) { changeTableValues(); } return null; } @Override protected void process(List progress) { } @Override protected void done() { if (str.equals("StartShedule")) { } } } private class SwingWorkerCompletionWaiter implements PropertyChangeListener { private String str; private String namePr; SwingWorkerCompletionWaiter(String str, String namePr) { this.str = str; this.namePr = namePr; } SwingWorkerCompletionWaiter(String namePr) { this.namePr = namePr; } @Override public void propertyChange(PropertyChangeEvent event) { if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.DONE == event.getNewValue()) { System.out.println("Thread Status with Name :" + str + ", SwingWorker Status is " + event.getNewValue()); } else if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.PENDING == event.getNewValue()) { System.out.println("Thread Status with Mame :" + str + ", SwingWorker Status is " + event.getNewValue()); } else if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.STARTED == event.getNewValue()) { System.out.println("Thread Status with Name :" + str + ", SwingWorker Status is " + event.getNewValue()); } else { System.out.println("SomeThing Wrong happends with Thread Status with Name :" + str); } } } } 

MODIFICARE:

aggiunto ri-generato da Future # get () nel metodo done () (da @takteek ottimo suggerimento)

 @Override protected void done() { if (str.equals("StartShedule")) { try { get(); //errLabel.setText(String.valueOf(get())); } catch (InterruptedException ie) { ie.printStackTrace(); } catch (ExecutionException ee) { ee.printStackTrace(); }catch (IllegalStateException is) { is.printStackTrace(); } } } 

ma l’output è ancora e ha solo Got exception , sarebbe così difficile ottenere qualsiasi eccezione da questo BlackBox

 run: Got exception Thread Status with Name :StartShedule, SwingWorker Status is STARTED Thread Status with Name :StartShedule, SwingWorker Status is DONE Got exception Thread Status with Name :StartShedule, SwingWorker Status is STARTED Thread Status with Name :StartShedule, SwingWorker Status is DONE Got exception Thread Status with Name :StartShedule, SwingWorker Status is STARTED Thread Status with Name :StartShedule, SwingWorker Status is DONE Got exception Thread Status with Name :StartShedule, SwingWorker Status is STARTED Thread Status with Name :StartShedule, SwingWorker Status is DONE BUILD SUCCESSFUL (total time: 13 seconds) 

Non sono sicuro che aggiunga molto, ma ho ottenuto l’attesa Caused by usando la variazione della risposta di takteek mostrata sotto. L’ho eseguito dalla riga di comando per essere sicuro che l’IDE non “aiutasse”.

 $ java -cp build / classs TableWithExecutor
 StartShedule: PENDING -> STARTED
 java.util.concurrent.ExecutionException: java.lang.ArrayIndexOutOfBoundsException: indice array fuori intervallo: 2
     a java.util.concurrent.FutureTask $ Sync.innerGet (FutureTask.java:222)
     a java.util.concurrent.FutureTask.get (FutureTask.java:83)
     a javax.swing.SwingWorker.get (SwingWorker.java:582)
     a TableWithExecutor $ MyTask.done (TableWithExecutor.java:103)
     a javax.swing.SwingWorker $ 5.run (SwingWorker.java:717)
     a javax.swing.SwingWorker $ DoSubmitAccumulativeRunnable.run (SwingWorker.java:814)
     a sun.swing.AccumulativeRunnable.run (AccumulativeRunnable.java:95)
     a javax.swing.SwingWorker $ DoSubmitAccumulativeRunnable.actionPerformsd (SwingWorker.java:824)
     a javax.swing.Timer.fireActionPerformsd (Timer.java:291)
     a javax.swing.Timer $ DoPostEvent.run (Timer.java:221)
     a java.awt.event.InvocationEvent.dispatch (InvocationEvent.java:209)
     a java.awt.EventQueue.dispatchEventImpl (EventQueue.java:677)
     a java.awt.EventQueue.access $ 000 (EventQueue.java:85)
     a java.awt.EventQueue $ 1.run (EventQueue.java:638)
     a java.awt.EventQueue $ 1.run (EventQueue.java:636)
     a java.security.AccessController.doPrivileged (metodo nativo)
     a java.security.AccessControlContext $ 1.doIntersectionPrivilege (AccessControlContext.java:87)
     a java.awt.EventQueue.dispatchEvent (EventQueue.java:647)
     a java.awt.EventDispatchThread.pumpOneEventForFilters (EventDispatchThread.java:296)
     a java.awt.EventDispatchThread.pumpEventsForFilter (EventDispatchThread.java:211)
     a java.awt.EventDispatchThread.pumpEventsForHierarchy (EventDispatchThread.java:201)
     a java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:196)
     a java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:188)
     a java.awt.EventDispatchThread.run (EventDispatchThread.java:122)
 Causato da: java.lang.ArrayIndexOutOfBoundsException: indice di matrice fuori intervallo: 2
     a java.util.Vector.get (Vector.java:694)
     a TableWithExecutor.changeTableValues ​​(TableWithExecutor.java:64)
     a TableWithExecutor.access $ 100 (TableWithExecutor.java:14)
     a TableWithExecutor $ MyTask.doInBackground (TableWithExecutor.java:92)
     a TableWithExecutor $ MyTask.doInBackground (TableWithExecutor.java:80)
     a javax.swing.SwingWorker $ 1.call (SwingWorker.java:277)
     a java.util.concurrent.FutureTask $ Sync.innerRun (FutureTask.java:303)
     a java.util.concurrent.FutureTask.run (FutureTask.java:138)
     a javax.swing.SwingWorker.run (SwingWorker.java:316)
     a java.util.concurrent.ThreadPoolExecutor $ Worker.runTask (ThreadPoolExecutor.java:886)
     a java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:908)
     a java.lang.Thread.run (Thread.java:680)
 StartShedule: STARTED -> DONE

Codice completo:

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.DateFormat; import java.util.Date; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import javax.swing.*; import javax.swing.table.*; /** @see https://stackoverflow.com/questions/7054627 */ public class TableWithExecutor extends JFrame { private static final int delay = 1000; private static final DateFormat df = DateFormat.getTimeInstance(); private String[] columnNames = {"Product", "Availability"}; private Object[][] data = {columnNames, columnNames, columnNames}; private DefaultTableModel model; private JTable table; private Executor executor = Executors.newCachedThreadPool(); private Timer timer; public TableWithExecutor() { model = new DefaultTableModel(data, columnNames); table = new JTable(model) { @Override public Class getColumnClass(int column) { return getValueAt(0, column).getClass(); } }; table.setDefaultRenderer(Date.class, new DefaultTableCellRenderer() { @Override protected void setValue(Object value) { setText((value == null) ? "" : df.format(value)); } }); table.setPreferredScrollableViewportSize(new Dimension(200, 100)); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane, BorderLayout.CENTER); timer = new Timer(delay, startCycle()); timer.setRepeats(true); timer.start(); } private Action startCycle() { return new AbstractAction(MyTask.STARTSCHEDULE) { @Override public void actionPerformsd(ActionEvent e) { executor.execute(new MyTask(MyTask.STARTSCHEDULE)); } }; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { TableWithExecutor frame = new TableWithExecutor(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } private class MyTask extends SwingWorker, DateRecord> { private static final String STARTSCHEDULE = "StartSchedule"; private String name = STARTSCHEDULE; MyTask(String name) { this.name = name; addPropertyChangeListener(new TaskListener(name)); } @Override protected List doInBackground() throws Exception { for (int row = 0; row < model.getRowCount(); row++) { Date date = new Date(); date.setTime(date.getTime() + row * 1000); publish(new DateRecord(row, date)); } return null; } @Override protected void process(List chunks) { for (DateRecord dr : chunks) { model.setValueAt(dr.date, dr.rowNumber, 1); } } @Override protected void done() { try { get(); } catch (Exception e) { e.printStackTrace(System.err); } } } private static class DateRecord { private int rowNumber; private Date date; public DateRecord(int recordNumber, Date date) { this.rowNumber = recordNumber; this.date = date; } } private static class TaskListener implements PropertyChangeListener { private String name; TaskListener(String name) { this.name = name; } @Override public void propertyChange(PropertyChangeEvent e) { System.out.println(name + ": " + e.getOldValue() + " -> " + e.getNewValue()); } } } 

Penso che il problema che stai incontrando sia che le eccezioni catturate nel thread in background vengono ridistribuite solo se chiami get() quando l’elaborazione è completa. Questo sembra essere un problema comune con SwingWorker.

Puoi cambiare la tua funzione done() in:

 @Override protected void done() { if (str.equals("StartShedule")) { try { get(); } catch (Exception ex) { // This exception was thrown during processing ex.printStackTrace(); } } } 

done() viene eseguito sul thread di invio dell’evento in modo da poter visualizzare da lì eventuali messaggi di errore. Spero che ne aiuti qualcuno.