> Java > java지도 시간 > 멀티스레딩을 위해 Executor 및 SwingWorker를 사용할 때 ArrayIndexOutOfBoundsException을 포착하는 방법은 무엇입니까?

멀티스레딩을 위해 Executor 및 SwingWorker를 사용할 때 ArrayIndexOutOfBoundsException을 포착하는 방법은 무엇입니까?

Mary-Kate Olsen
풀어 주다: 2024-12-15 08:52:16
원래의
212명이 탐색했습니다.

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

멀티 스레딩을 위해 Executor 및 SwingWorker를 사용할 때 ArrayIndexOutOfBoundsException을 얻는 방법

질문:

저는 SwingWorker에 Executor를 사용하고 있습니다. 멀티스레딩에 문제가 발생했습니다. 존재하지 않는 Vector의 요소에 액세스하면 코드가 해당 요소를 무시하는 것 같습니다. 이 예외를 얻는 방법은 무엇입니까?

답변:

SwingWorker의 done() 메서드에서 Future#get()에서 얻은 예외를 다시 발생시키면 질문의 예외가 가능해집니다.

수정된 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿