ホームページ >Java >&#&チュートリアル >マルチスレッドに Executor と SwingWorker を使用するときに ArrayIndexOutOfBoundsException をキャッチするにはどうすればよいですか?

マルチスレッドに Executor と SwingWorker を使用するときに ArrayIndexOutOfBoundsException をキャッチするにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-15 08:52:16217ブラウズ

How to Catch ArrayIndexOutOfBoundsException When Using Executor and SwingWorker for Multithreading?

マルチスレッドに Executor と SwingWorker を使用するときに ArrayIndexOutOfBoundsException を取得する方法

質問:

SwingWorker の Executor を使用していますマルチスレッドで問題が発生しました。存在しない Vector の要素にアクセスすると、コードはその要素を無視するようです。この例外を取得するにはどうすればよいでしょうか?

回答:

Future#get() で取得した例外を SwingWorker の Done() メソッドで再スローすることで、質問の例外が発生する可能性があります。

変更された done() メソッドは次のようになります。

@Override
protected void done() {
    try {
        get();
    } catch (InterruptedException | ExecutionException | IllegalStateException e) {
        e.printStackTrace();
    }
}

done() メソッドでこれらの例外をキャッチすることにより、SwingWorker はアプリケーションのハンドル例外で使用するためにそれらの例外を再スローできます。

完全なコード例:

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 java.util.concurrent.Future;
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 actionPerformed(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<List<DateRecord>, DateRecord> {

        private static final String STARTSCHEDULE = "StartSchedule";
        private String name = STARTSCHEDULE;

        MyTask(String name) {
            this.name = name;
            addPropertyChangeListener(new TaskListener(name));
        }

        @Override
        protected List<DateRecord> 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<DateRecord> 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());
        }
    }
}

上記のコードは、Executor と SwingWorker を使用してマルチスレッドを実行し、done() メソッドで例外を再スローする方法を示しています。 、ArrayIndexOutOfBoundsException 例外をキャッチして処理します。

以上がマルチスレッドに Executor と SwingWorker を使用するときに ArrayIndexOutOfBoundsException をキャッチするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。