【问题标题】:Java, multi-thread application,working main window when computingJava,多线程应用程序,计算时工作的主窗口
【发布时间】:2017-03-26 12:50:07
【问题描述】:

我想请教如何设计应用程序。目前,我想将一个处理大数据的统计应用程序重写为多线程版本。我的主要语言是 C++,抱歉我的初学者问题:-)。

现有应用程序基于以下模型。有一个 MainWindow 类持续显示涉及当前缩放操作 (GUI) 的先前结果。每个统计计算都基于自己的类,获取输入数据、执行计算、显示结果及其可视化(基于摆动)。

不幸的是,这个库没有写成多线程。它有一个不良后果:在计算运行时,无法使用 MainWindow(浏览所有结果,直到获得新结果);它被“冻结”了……

昨天,我尝试提出一个单一的概念更新:

public class MainWindow extends JFame {

private void fButtonActionPerformed(java.awt.event.ActionEvent e) {
   //Get data, single thread
   Matrix A = getData();  //Input data (block matrix)
   Matrix B;              //Output data (block matrix)

   //Computation in a separate thread
   FunctionMT f = new FunctionMT (A, B);
   Thread t = new Thread(f);  
   t.start();    // Starting the thread

   //Display results in a form
   results.print(B);

   //Update graphic results
   scene.update(B);
   scene.repaint();
}

示例函数类 FunctionMT 扩展了 Thread 库

public class FunctionMT extends Thread{
    private final Matrix A;
    private Matrix B;

    public FunctionMT (final Matrix A_, Matrix B_) {A = A_; B = B_;}
    public void run () { spDecomposition();}
    public void spDecomposition() { 
        for (int i = 0; i < A.size; i++)
            for (int j = 0; j < A.size; j++)
                B(i,j) = f(A(i,));} //Some computationally hard step
}     

矩阵A是输入矩阵,B代表输出。计算在使用 FunctionMT 实例的单个线程中执行...

当计算在单线程中运行时,可以使用主窗口。不幸的是,在计算停止之前重新绘制结果。

我尝试添加一个join方法()

 ...
 Thread t = new Thread(f);  
 t.start();    // Starting the thread

 try{t.join();}  //Wait for its end
 catch(InterruptedException e) {e.printStackTrace();}

 results.print(B);

 scene.update(B);
 scene.repaint();
 ...

等待处理结果。不幸的是,它使主窗口冻结。

如何提出一个多线程计算,以便在计算期间能够与主窗口一起工作以及表单等待计算完成?

是否可以在循环中添加一些处理系统消息的函数?

for (int i = 0; i < A.size; i++)
     for (int j = 0; j < A.size; j++)
          processSystemMessages();
          B(i,j) = f(A(i,));}

另一种解决方案可能会加入计算算法并将结果显示到同一个线程中,但它看起来很丑 :-) 并破坏了设计模式。

非常感谢您的帮助...

【问题讨论】:

    标签: java multithreading computation


    【解决方案1】:

    试试这个:

    更新:更松散的耦合

    public class MainWindow extends JFrame {
    
        private void fButtonActionPerformed(java.awt.event.ActionEvent e) {
    
            // ...
    
            FunctionMT f = new FunctionMT (A, B, new Runnable() {
                @Override
                public void run() {
                    results.print(B);
                    scene.update(B);
                    scene.repaint();
                }
            });
            Thread t = new Thread(f);
            t.start();
    
            // Wait for computation:
            // won't do it here.
            // results.print(B);
            // scene.update(B);
            // scene.repaint();
        }
    }
    
    public class FunctionMT extends Runnable {
    
        // ...
    
        private Runnable callback;
    
        public FunctionMT (final Matrix A_, Matrix B_, Runnable callback) {
    
            // ...
    
            this.callback = callback;
        }
    
        private void spDecomposition() {
    
            // Do computation.
    
            SwingUtilities.invokeLater(callback);
        }
    }
    

    【讨论】:

    • @nandsito:感谢您的评论。问题是计算、打印结果和更新场景都加入了同一个线程和方法。它导致类 FunctionMT 的巨大重新定义(对表单、图形对象等的引用)。不幸的是,它打破了一种设计模式......
    • @justik 你的担心是有道理的。我更新了我的答案,请看看它是否符合您的需求
    • @nandsito:太好了,它有效!再一次非常感谢你 !只有一个简短的评论:而不是 SwingUtilities.html.invokeLater 它应该是 SwingUtilities.invokeLater
    • @justik 我的错误...我抄错了 javadoc url
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多