实时处理传入的数据流

时间:2016-03-09 10:19:38

标签: java

我读了一个数字文件,我想点击一个按钮。单击该按钮时,数字将输出平均值而不是仅输出数字,而不会中断传入的数据流。

我想要实时操纵流。这就是我想知道的。

如何做到这一点?

2 个答案:

答案 0 :(得分:1)

这是一个概念验证应用程序。它使用SwingWorker计数从0到99,每次添加一个小延迟。按钮开始计数,在计数期间,允许您将输出的数字加倍。请注意,类成员doubleMe标记为volatile,因为它是跨线程读取的。

请注意,我使用Java 8来实现紧凑性。

public class MainFrame extends JFrame {
    private static final long serialVersionUID = 1L;

    public class WorkerTest extends SwingWorker<Void, Integer> {
        public volatile boolean doubleMe = false;

        protected Void doInBackground() throws Exception {
            for(int i=0; i<100; i++) {
                publish(doubleMe ? i*2 : i);

                Thread.sleep(100);
            }
            return null;
        }

        @Override
        protected void process(List<Integer> numberList) {
            super.process(arg0);

            numberList.forEach(System.out::println);
        }
    }

    private WorkerTest worker = null;
    private final JButton btn;

    public MainFrame() {
        setMinimumSize(new Dimension(200, 100));

        btn = new JButton("Go!");

        btn.addActionListener(ae -> {
            if(worker == null || worker.isDone()) {
                btn.setText("Toggle double!");

                worker = new WorkerTest();
                worker.addPropertyChangeListener(l -> {
                    if("state".equals(l.getPropertyName()) && StateValue.DONE.equals(l.getNewValue())) {
                        btn.setText("Go!");
                    }
                });
                worker.execute();
            } else {
                worker.doubleMe = !worker.doubleMe;
            }
        });
        add(btn);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            MainFrame mf = new MainFrame();
            mf.setVisible(true);
        });
    }
}

在你的情况下,你会读数字,而不是生成数字,但概念是相同的。 doubleMe充当一种与线程通信的方式,以便在线程仍在工作时改变其行为。如果这回答了你的问题,请告诉我。

答案 1 :(得分:0)

我猜你正在寻找的是一种天真的方法,可以通过实时数字流取平均值。

您可以这样做:

private int sum = 0; private int n = 0; //没有。 nums阅读

func(){
 while / for:
 nextNum = // code to read number in a loop
 sum += nextNum;
 n++;
}

然后您可以使用事件处理程序来捕获按钮单击事件 并在按钮单击时,您可以返回avg = sum / n。

然而,正如Neil指出的那样,如果你想要不间断的流并且还要避免竞争条件,你应该使用线程。

编辑:根据竞争条件,我的意思是假设您在更新总和值但未更新n时单击。在这种情况下,你会得到错误的平均结果。