如何在 Java 中与两(2)个 SwingWorker 类共享数据

发布于 2024-11-10 02:56:54 字数 138 浏览 3 评论 0原文

我有两个 SwingWorker 类:FileLineCounterThread 和 FileDivisionThread

我将执行这两个线程。当行计数线程完成时,它将结果传递给文件分割线程。

我不知道如何将结果传递给启动的线程。

I have two SwingWorker class: FileLineCounterThread and FileDivisionThread

I will execute the two threads. When the lines counting thread finishes, it will pass the result to File Division thread.

I do not have an idea on how to pass the result to started thread.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

分分钟 2024-11-17 02:56:54
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

public class ExecutorAndSwingWorker2 {

    private JFrame frame = new JFrame();
    private JButton button1;
    private JButton button2;
    private JButton button3;
    private JButton button4;
    private JPanel buttonPanel = new JPanel();
    private Executor executor = Executors.newCachedThreadPool();
    private javax.swing.Timer timer1;
    private javax.swing.Timer timer2;
    private javax.swing.Timer timer3;
    private javax.swing.Timer timer4;
    private Random random = new Random();

    public ExecutorAndSwingWorker2() {
        button1 = new JButton("  Executor + SwingWorker Thread No.1  ");
        button1.setFocusable(false);
        button2 = new JButton("  Executor + SwingWorker Thread No.2  ");
        button3 = new JButton("  Executor + SwingWorker Thread No.3  ");
        button4 = new JButton("  Executor + SwingWorker Thread No.4  ");
        buttonPanel = new JPanel();
        buttonPanel.setBorder(new EmptyBorder(15, 15, 15, 15));
        buttonPanel.setLayout(new GridLayout(2, 2, 20, 20));
        buttonPanel.add(button1);
        buttonPanel.add(button2);
        buttonPanel.add(button3);
        buttonPanel.add(button4);
        frame.setTitle("Shaking Button Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(buttonPanel);
        frame.setPreferredSize(new Dimension(700, 170));
        frame.setLocation(150, 100);
        frame.pack();
        frame.setVisible(true);
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton1")); // non on EDT
    }

    private void startButton1() {
        System.out.println("Starting long Thread == startButton1()");
        try {
            Thread.sleep(15000);
        } catch (InterruptedException ex) {
        }
    }

    private void startButton2() {
        System.out.println("Starting long Thread == startButton2()");
        try {
            Thread.sleep(17500);
        } catch (InterruptedException ex) {
        }
    }

    private void startButton3() {
        System.out.println("Starting long Thread == startButton3()");
        try {
            Thread.sleep(12500);
        } catch (InterruptedException ex) {
        }
    }

    private void startButton4() {
        System.out.println("Starting long Thread == startButton4()");
        try {
            Thread.sleep(20000);
        } catch (InterruptedException ex) {
        }
    }

    private void colorAction1() {
        timer1 = new Timer(1000, new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                random = new Random();
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        button1.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
                        button1.validate();
                        button1.repaint();
                    }
                });
            }
        });
        timer1.setDelay(500);
        timer1.setRepeats(true);
        timer1.start();
    }

    private void colorAction2() {
        timer2 = new Timer(1200, new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                random = new Random();
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        button2.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
                        button2.validate();
                        button2.repaint();
                    }
                });
            }
        });
        timer2.setDelay(500);
        timer2.setRepeats(true);
        timer2.start();
    }

    private void colorAction3() {
        timer3 = new Timer(1400, new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                random = new Random();
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        button3.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
                        button3.validate();
                        button3.repaint();
                    }
                });
            }
        });
        timer3.setDelay(500);
        timer3.setRepeats(true);
        timer3.start();
    }

    private void colorAction4() {
        timer4 = new Timer(1600, new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                random = new Random();
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        button4.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
                        button4.validate();
                        button4.repaint();
                    }
                });
            }
        });
        timer4.setDelay(500);
        timer4.setRepeats(true);
        timer4.start();
    }

    private void endButton1() {
        timer1.stop();
        button1.setBackground(null);
        System.out.println("Long Thread Ends == startButton1()");
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton3")); // non on EDT
    }

    private void endButton2() {
        timer2.stop();
        button2.setBackground(null);
        System.out.println("Long Thread Ends == startButton2()");
    }

    private void endButton3() {
        timer3.stop();
        button3.setBackground(null);
        System.out.println("Long Thread Ends == startButton3()");
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton2")); // non on EDT
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton4")); // non on EDT
    }

    private void endButton4() {
        timer4.stop();
        button4.setBackground(null);
        System.out.println("Long Thread Ends == startButton4()");
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton1")); // non on EDT
    }

    private class MyTask extends SwingWorker<Void, Integer> {

        private String str;
        private String namePr;
        private JDialog dialog = new JDialog();

        MyTask(String str) {
            this.str = str;
            addPropertyChangeListener(new SwingWorkerCompletionWaiter(dialog, str, namePr));
        }

        @Override
        protected Void doInBackground() throws Exception {
            if (str.equals("startButton1")) {
                colorAction1();
                startButton1();
            } else if (str.equals("startButton2")) {
                colorAction2();
                startButton2();
            } else if (str.equals("startButton3")) {
                colorAction3();
                startButton3();
            } else if (str.equals("startButton4")) {
                colorAction4();
                startButton4();
            }
            return null;
        }

        @Override
        protected void process(List<Integer> progress) {
            System.out.println(str + " " + progress.get(progress.size() - 1));
        }

        @Override
        protected void done() {
            if (str.equals("startButton1")) {
                endButton1();
            } else if (str.equals("startButton2")) {
                endButton2();
            } else if (str.equals("startButton3")) {
                endButton3();
            } else if (str.equals("startButton4")) {
                endButton4();
            }
        }
    }

    private class SwingWorkerCompletionWaiter implements PropertyChangeListener {

        private JDialog dialog;
        private String str;
        private String namePr;

        SwingWorkerCompletionWaiter(JDialog dialog, String str, String namePr) {
            this.dialog = dialog;
            this.str = str;
            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("Thread Status with Name :" + str + ", Something wrong happends ");
            }
        }
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ExecutorAndSwingWorker2 executorAndSwingWorker = new ExecutorAndSwingWorker2();
            }
        });
    }
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

public class ExecutorAndSwingWorker2 {

    private JFrame frame = new JFrame();
    private JButton button1;
    private JButton button2;
    private JButton button3;
    private JButton button4;
    private JPanel buttonPanel = new JPanel();
    private Executor executor = Executors.newCachedThreadPool();
    private javax.swing.Timer timer1;
    private javax.swing.Timer timer2;
    private javax.swing.Timer timer3;
    private javax.swing.Timer timer4;
    private Random random = new Random();

    public ExecutorAndSwingWorker2() {
        button1 = new JButton("  Executor + SwingWorker Thread No.1  ");
        button1.setFocusable(false);
        button2 = new JButton("  Executor + SwingWorker Thread No.2  ");
        button3 = new JButton("  Executor + SwingWorker Thread No.3  ");
        button4 = new JButton("  Executor + SwingWorker Thread No.4  ");
        buttonPanel = new JPanel();
        buttonPanel.setBorder(new EmptyBorder(15, 15, 15, 15));
        buttonPanel.setLayout(new GridLayout(2, 2, 20, 20));
        buttonPanel.add(button1);
        buttonPanel.add(button2);
        buttonPanel.add(button3);
        buttonPanel.add(button4);
        frame.setTitle("Shaking Button Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(buttonPanel);
        frame.setPreferredSize(new Dimension(700, 170));
        frame.setLocation(150, 100);
        frame.pack();
        frame.setVisible(true);
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton1")); // non on EDT
    }

    private void startButton1() {
        System.out.println("Starting long Thread == startButton1()");
        try {
            Thread.sleep(15000);
        } catch (InterruptedException ex) {
        }
    }

    private void startButton2() {
        System.out.println("Starting long Thread == startButton2()");
        try {
            Thread.sleep(17500);
        } catch (InterruptedException ex) {
        }
    }

    private void startButton3() {
        System.out.println("Starting long Thread == startButton3()");
        try {
            Thread.sleep(12500);
        } catch (InterruptedException ex) {
        }
    }

    private void startButton4() {
        System.out.println("Starting long Thread == startButton4()");
        try {
            Thread.sleep(20000);
        } catch (InterruptedException ex) {
        }
    }

    private void colorAction1() {
        timer1 = new Timer(1000, new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                random = new Random();
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        button1.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
                        button1.validate();
                        button1.repaint();
                    }
                });
            }
        });
        timer1.setDelay(500);
        timer1.setRepeats(true);
        timer1.start();
    }

    private void colorAction2() {
        timer2 = new Timer(1200, new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                random = new Random();
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        button2.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
                        button2.validate();
                        button2.repaint();
                    }
                });
            }
        });
        timer2.setDelay(500);
        timer2.setRepeats(true);
        timer2.start();
    }

    private void colorAction3() {
        timer3 = new Timer(1400, new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                random = new Random();
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        button3.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
                        button3.validate();
                        button3.repaint();
                    }
                });
            }
        });
        timer3.setDelay(500);
        timer3.setRepeats(true);
        timer3.start();
    }

    private void colorAction4() {
        timer4 = new Timer(1600, new AbstractAction() {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                random = new Random();
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        button4.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
                        button4.validate();
                        button4.repaint();
                    }
                });
            }
        });
        timer4.setDelay(500);
        timer4.setRepeats(true);
        timer4.start();
    }

    private void endButton1() {
        timer1.stop();
        button1.setBackground(null);
        System.out.println("Long Thread Ends == startButton1()");
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton3")); // non on EDT
    }

    private void endButton2() {
        timer2.stop();
        button2.setBackground(null);
        System.out.println("Long Thread Ends == startButton2()");
    }

    private void endButton3() {
        timer3.stop();
        button3.setBackground(null);
        System.out.println("Long Thread Ends == startButton3()");
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton2")); // non on EDT
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton4")); // non on EDT
    }

    private void endButton4() {
        timer4.stop();
        button4.setBackground(null);
        System.out.println("Long Thread Ends == startButton4()");
        executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton1")); // non on EDT
    }

    private class MyTask extends SwingWorker<Void, Integer> {

        private String str;
        private String namePr;
        private JDialog dialog = new JDialog();

        MyTask(String str) {
            this.str = str;
            addPropertyChangeListener(new SwingWorkerCompletionWaiter(dialog, str, namePr));
        }

        @Override
        protected Void doInBackground() throws Exception {
            if (str.equals("startButton1")) {
                colorAction1();
                startButton1();
            } else if (str.equals("startButton2")) {
                colorAction2();
                startButton2();
            } else if (str.equals("startButton3")) {
                colorAction3();
                startButton3();
            } else if (str.equals("startButton4")) {
                colorAction4();
                startButton4();
            }
            return null;
        }

        @Override
        protected void process(List<Integer> progress) {
            System.out.println(str + " " + progress.get(progress.size() - 1));
        }

        @Override
        protected void done() {
            if (str.equals("startButton1")) {
                endButton1();
            } else if (str.equals("startButton2")) {
                endButton2();
            } else if (str.equals("startButton3")) {
                endButton3();
            } else if (str.equals("startButton4")) {
                endButton4();
            }
        }
    }

    private class SwingWorkerCompletionWaiter implements PropertyChangeListener {

        private JDialog dialog;
        private String str;
        private String namePr;

        SwingWorkerCompletionWaiter(JDialog dialog, String str, String namePr) {
            this.dialog = dialog;
            this.str = str;
            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("Thread Status with Name :" + str + ", Something wrong happends ");
            }
        }
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ExecutorAndSwingWorker2 executorAndSwingWorker = new ExecutorAndSwingWorker2();
            }
        });
    }
}
握住你手 2024-11-17 02:56:54

SwingWorker.execute()buggy 并且会只串行执行任务。使用 ExecutorService.execute() 实现并发:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RunnableFuture;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;

public class MyFrame extends JFrame implements ActionListener {

    /**
     * Test Driver
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MyFrame frame = new MyFrame("Swing Concurrency Test");
                frame.setVisible(true);
            }
        });
    }

    /**
     * Thread Executor
     * (must be explicitly shutdown, see WindowAdapter below)
     */
    private final ExecutorService exec = Executors.newFixedThreadPool(2);

    /**
     * Button action
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        button.setEnabled(false);
        textArea.append("\nStarting both tasks...\n");

        // start both tasks, pass a reference to outer task
        FileLineCounterThread counterTask = new FileLineCounterThread();
        exec.execute(counterTask);
        FileDivisionThread divisionTask = new FileDivisionThread(counterTask);
        exec.execute(divisionTask);
    }

    /**
     * Counter task
     */
    private class FileLineCounterThread extends SwingWorker<Long, String> {
        private String template = "[FileLineCounterThread] %s\n";

        @Override
        protected Long doInBackground() throws Exception {
            // do some work
            publish("started...");
            Thread.sleep(10000);

            // return the result
            return 42L;
        }

        @Override
        protected void process(List<String> chunks) {
            for (String chunk : chunks) {
                textArea.append(String.format(template, chunk));
            }
        }

        @Override
        protected void done() {
            try {
                textArea.append(String.format(
                        template, "complete.  Counted: " + get()));
            }
            catch (Exception e) {
                // catch any exceptions thrown during execution
                e.printStackTrace();
            }
        }
    }

    /**
     * File Division task 
     */
    private class FileDivisionThread extends SwingWorker<String, String> {
        private RunnableFuture<Long> counterTask;
        private String template = "    [FileDivisionThread] %s\n";

        public FileDivisionThread(RunnableFuture<Long> counterTask) {
            this.counterTask = counterTask;
        }

        @Override
        protected String doInBackground() throws Exception {
            // do some initial work
            publish("started...");
            Thread.sleep(2000);

            // wait for other task to complete and get result
            publish("Waiting for line counter to finish...");
            long numLines = counterTask.get(); 
            publish("Line count received: " + numLines);

            // do the rest of the work and return result
            Thread.sleep(5000);
            return "complete.";
        }

        @Override
        protected void process(List<String> chunks) {
            for (String chunk : chunks) {
                textArea.append(String.format(template, chunk));
            }
        }

        @Override
        protected void done() {
            try {
                textArea.append(String.format(template, get()));
                button.setEnabled(true);
            }
            catch (Exception e) {
                // catch any exceptions thrown during execution
                e.printStackTrace();
            }
        }
    }

    /////////////////////////
    //// GUI Boilerplate ////
    /////////////////////////

    private JScrollPane scroller = new JScrollPane();
    private JTextArea textArea = new JTextArea();
    private JButton button = new JButton("Start");

    public MyFrame(String windowTitle) {
        super(windowTitle);
        initComponents();
    }

    private void initComponents() {
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                exec.shutdownNow();
                System.exit(0);
            }
        });
        button = new JButton("Start");
        button.addActionListener(this);
        textArea = new JTextArea();
        textArea.setColumns(35);
        textArea.setRows(15);
        scroller.setViewportView(textArea);

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new GridBagLayout());

        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new Insets(10, 0, 0, 0);
        getContentPane().add(button, gridBagConstraints);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new Insets(10, 10, 10, 10);
        getContentPane().add(scroller, gridBagConstraints);

        pack();
    }
}

SwingWorker.execute() is buggy and will only execute tasks serially. Use ExecutorService.execute() for concurrency:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RunnableFuture;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;

public class MyFrame extends JFrame implements ActionListener {

    /**
     * Test Driver
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MyFrame frame = new MyFrame("Swing Concurrency Test");
                frame.setVisible(true);
            }
        });
    }

    /**
     * Thread Executor
     * (must be explicitly shutdown, see WindowAdapter below)
     */
    private final ExecutorService exec = Executors.newFixedThreadPool(2);

    /**
     * Button action
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        button.setEnabled(false);
        textArea.append("\nStarting both tasks...\n");

        // start both tasks, pass a reference to outer task
        FileLineCounterThread counterTask = new FileLineCounterThread();
        exec.execute(counterTask);
        FileDivisionThread divisionTask = new FileDivisionThread(counterTask);
        exec.execute(divisionTask);
    }

    /**
     * Counter task
     */
    private class FileLineCounterThread extends SwingWorker<Long, String> {
        private String template = "[FileLineCounterThread] %s\n";

        @Override
        protected Long doInBackground() throws Exception {
            // do some work
            publish("started...");
            Thread.sleep(10000);

            // return the result
            return 42L;
        }

        @Override
        protected void process(List<String> chunks) {
            for (String chunk : chunks) {
                textArea.append(String.format(template, chunk));
            }
        }

        @Override
        protected void done() {
            try {
                textArea.append(String.format(
                        template, "complete.  Counted: " + get()));
            }
            catch (Exception e) {
                // catch any exceptions thrown during execution
                e.printStackTrace();
            }
        }
    }

    /**
     * File Division task 
     */
    private class FileDivisionThread extends SwingWorker<String, String> {
        private RunnableFuture<Long> counterTask;
        private String template = "    [FileDivisionThread] %s\n";

        public FileDivisionThread(RunnableFuture<Long> counterTask) {
            this.counterTask = counterTask;
        }

        @Override
        protected String doInBackground() throws Exception {
            // do some initial work
            publish("started...");
            Thread.sleep(2000);

            // wait for other task to complete and get result
            publish("Waiting for line counter to finish...");
            long numLines = counterTask.get(); 
            publish("Line count received: " + numLines);

            // do the rest of the work and return result
            Thread.sleep(5000);
            return "complete.";
        }

        @Override
        protected void process(List<String> chunks) {
            for (String chunk : chunks) {
                textArea.append(String.format(template, chunk));
            }
        }

        @Override
        protected void done() {
            try {
                textArea.append(String.format(template, get()));
                button.setEnabled(true);
            }
            catch (Exception e) {
                // catch any exceptions thrown during execution
                e.printStackTrace();
            }
        }
    }

    /////////////////////////
    //// GUI Boilerplate ////
    /////////////////////////

    private JScrollPane scroller = new JScrollPane();
    private JTextArea textArea = new JTextArea();
    private JButton button = new JButton("Start");

    public MyFrame(String windowTitle) {
        super(windowTitle);
        initComponents();
    }

    private void initComponents() {
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                exec.shutdownNow();
                System.exit(0);
            }
        });
        button = new JButton("Start");
        button.addActionListener(this);
        textArea = new JTextArea();
        textArea.setColumns(35);
        textArea.setRows(15);
        scroller.setViewportView(textArea);

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new GridBagLayout());

        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new Insets(10, 0, 0, 0);
        getContentPane().add(button, gridBagConstraints);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new Insets(10, 10, 10, 10);
        getContentPane().add(scroller, gridBagConstraints);

        pack();
    }
}
卸妝后依然美 2024-11-17 02:56:54

用于字符数据和字符数据的 PipedReader/Writer 二进制数据的 PipedInput/OutputStream。

java.io 中

问候,
史蒂芬

PipedReader/Writer for character data & PipedInput/OutputStream for binary data

in java.io.

Regards,
Stéphane

深府石板幽径 2024-11-17 02:56:54

永远不要放弃,永远不要放弃 Executor 和 SwingWorker

1/ Executor 和 SwingWorker

2/ 保存并检查由 Executor 和实时 SwingWorkers 线程,旨在避免捕获上述错误

3/检查最大数量对于执行者或限制为最终成员

编辑按OP的要求更改

import java.beans.*;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class ExecutorAndSwingWorker1 {

    private static Executor executor = Executors.newCachedThreadPool();

    private static void startButton1() {
        System.out.println("Starting long Tread == startButton1()");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
        }
    }

    private static void startButton2() {
        System.out.println("Starting long Tread == startButton2()");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException ex) {
        }
    }

    private static void startButton3() {
        System.out.println("Starting long Tread == startButton3()");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException ex) {
        }
    }

    private static void startButton4() {
        System.out.println("Starting long Tread == startButton4()");
        try {
            Thread.sleep(500);
        } catch (InterruptedException ex) {
        }
    }

    private static void endButton1() {
        System.out.println("Long Tread Ends == startButton1()");
        executor.execute(new ExecutorAndSwingWorker1.MyTask("startButton3")); // non on EDT
    }

    private static void endButton2() {
        System.out.println("Long Tread Ends == startButton2()");
        executor.execute(new ExecutorAndSwingWorker1.MyTask("startButton4")); // non on EDT
    }

    private static void endButton3() {
        System.out.println("Long Tread Ends == startButton3()");
    }

    private static void endButton4() {
        System.out.println("Long Tread Ends == startButton3()");
    }

    private static class MyTask extends SwingWorker<Void, Integer> {

        private String str;
        private String namePr;
        private JDialog dialog = new JDialog();

        MyTask(String str) {
            this.str = str;
            addPropertyChangeListener(new SwingWorkerCompletionWaiter(dialog, str, namePr));
        }

        @Override
        protected Void doInBackground() throws Exception {
            if (str.equals("startButton1")) {
                startButton1();
            } else if (str.equals("startButton2")) {
                startButton2();
            } else if (str.equals("startButton3")) {
                startButton3();
            } else if (str.equals("startButton4")) {
                startButton4();
            }
            return null;
        }

        @Override
        protected void process(List<Integer> progress) {
            System.out.println(str + " " + progress.get(progress.size() - 1));
        }

        @Override
        protected void done() {
            if (str.equals("startButton1")) {
                endButton1();
            } else if (str.equals("startButton2")) {
                endButton2();
            } else if (str.equals("startButton3")) {
                endButton3();
            } else if (str.equals("startButton4")) {
                endButton4();
            }
        }
    }

    private static class SwingWorkerCompletionWaiter implements PropertyChangeListener {

        private JDialog dialog;
        private String str;
        private String namePr;

        SwingWorkerCompletionWaiter(JDialog dialog, String str, String namePr) {
            this.dialog = dialog;
            this.str = str;
            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("Thread Status with Name :" + str + ", Something wrong happends ");
            }
        }
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                executor.execute(new ExecutorAndSwingWorker1.MyTask("startButton1")); // non on EDT
                executor.execute(new ExecutorAndSwingWorker1.MyTask("startButton2")); // non on EDT
            }
        });
    }

    private ExecutorAndSwingWorker1() {
    }
}

never hands up, never surrender its possible with Executor and SwingWorker

1/ bug for Executor and SwingWorker

2/ hold and check number of thread started by Executor and live SwingWorkers threads with intentions to avoid caught above mentioned bug

3/ check maximum numbers for Executor or restict that to final munber

EDIT changed by OP's requirements

import java.beans.*;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class ExecutorAndSwingWorker1 {

    private static Executor executor = Executors.newCachedThreadPool();

    private static void startButton1() {
        System.out.println("Starting long Tread == startButton1()");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
        }
    }

    private static void startButton2() {
        System.out.println("Starting long Tread == startButton2()");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException ex) {
        }
    }

    private static void startButton3() {
        System.out.println("Starting long Tread == startButton3()");
        try {
            Thread.sleep(1500);
        } catch (InterruptedException ex) {
        }
    }

    private static void startButton4() {
        System.out.println("Starting long Tread == startButton4()");
        try {
            Thread.sleep(500);
        } catch (InterruptedException ex) {
        }
    }

    private static void endButton1() {
        System.out.println("Long Tread Ends == startButton1()");
        executor.execute(new ExecutorAndSwingWorker1.MyTask("startButton3")); // non on EDT
    }

    private static void endButton2() {
        System.out.println("Long Tread Ends == startButton2()");
        executor.execute(new ExecutorAndSwingWorker1.MyTask("startButton4")); // non on EDT
    }

    private static void endButton3() {
        System.out.println("Long Tread Ends == startButton3()");
    }

    private static void endButton4() {
        System.out.println("Long Tread Ends == startButton3()");
    }

    private static class MyTask extends SwingWorker<Void, Integer> {

        private String str;
        private String namePr;
        private JDialog dialog = new JDialog();

        MyTask(String str) {
            this.str = str;
            addPropertyChangeListener(new SwingWorkerCompletionWaiter(dialog, str, namePr));
        }

        @Override
        protected Void doInBackground() throws Exception {
            if (str.equals("startButton1")) {
                startButton1();
            } else if (str.equals("startButton2")) {
                startButton2();
            } else if (str.equals("startButton3")) {
                startButton3();
            } else if (str.equals("startButton4")) {
                startButton4();
            }
            return null;
        }

        @Override
        protected void process(List<Integer> progress) {
            System.out.println(str + " " + progress.get(progress.size() - 1));
        }

        @Override
        protected void done() {
            if (str.equals("startButton1")) {
                endButton1();
            } else if (str.equals("startButton2")) {
                endButton2();
            } else if (str.equals("startButton3")) {
                endButton3();
            } else if (str.equals("startButton4")) {
                endButton4();
            }
        }
    }

    private static class SwingWorkerCompletionWaiter implements PropertyChangeListener {

        private JDialog dialog;
        private String str;
        private String namePr;

        SwingWorkerCompletionWaiter(JDialog dialog, String str, String namePr) {
            this.dialog = dialog;
            this.str = str;
            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("Thread Status with Name :" + str + ", Something wrong happends ");
            }
        }
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                executor.execute(new ExecutorAndSwingWorker1.MyTask("startButton1")); // non on EDT
                executor.execute(new ExecutorAndSwingWorker1.MyTask("startButton2")); // non on EDT
            }
        });
    }

    private ExecutorAndSwingWorker1() {
    }
}
空城缀染半城烟沙 2024-11-17 02:56:54

我不确定这是您应该使用的解决方案,并且它破坏了您使用 SwingWorker 获得的简单性和安全性,但为了完整起见,我将提及它。

将两个字段放在两个线程都可以看到的位置:一个布尔值,称为 hasValue,初始化为 false,以及一个 int(或 long),称为 countValue。两者都必须声明为易失性。当计数器线程完成后,将计数放入 countValue 中。 然后hasValue设置为true。然后,除法线程可以定期检查“hasValue”并在可用时获取计数。

如果该除法在获得计数后提供的值会更准确,那么就可以了。更有可能的是,它正在做一些工作,然后等待计数。在本例中,设置名为 countMonitor 的第三个字段,定义为 final Object。当它完成初始工作时,让它检查hasValue。如果是 true,则获取该值并继续。如果为 false,则调用 countMonitor 上的 wait 方法,并在收到通知时继续。计数器线程完成后,应始终在将值放入 hasValue 和 <代码>计数值。

我在这里遗漏了一点。 Object 的 javadoc 将告诉您所需的同步和检查的异常。您的设计足够简单,您不会被多线程生成的常见超自然恐怖故事所困扰。我希望。但如果您走这条路,您可能需要做一些研究。 (如果您在同一会话中重复整个过程,您肯定想要进行大量研究。)

I am not sure this is a solution you should use, and it undermines the simplicity and safety you get from using SwingWorker, but I'll mention it for completeness.

Put two fields where both threads can see them: one boolean, called hasValue, initialized to false, and one int (or long) called countValue. Both must be declared as volatile. When the counter thread is done, put the count in countValue. Then set hasValue to true. The division thread can then check `hasValue' periodically and grab the count when it is available.

If the division is providing values that will be more accurate once it gets the count, this will do. More likely, it is doing some work, then waiting for the count. In this case, set up a third field called countMonitor, defined as final Object. When it finishes the initial work, have it check hasValue. If it's true, grab the value and continue. If it's false, call the wait method on countMonitor and continue when notified. The counter thread, when done, should always call the notifyAll method on countMonitor after putting values in hasValue and countValue.

I've left out a bit here. The javadoc for Object will tell you about needed synchronization and checked exceptions. Your design is straightforward enough that you won't be troubled with the usual supernatural horror stories multi-threading generates. I hope. But you might want to do a bit of research if you go this route. (If you repeat the whole process in the same session, you will definitely want to do a lot of research.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文