Java线程:程序滞后(无响应)只是后台进程的中途

时间:2017-03-23 16:01:26

标签: java multithreading swingworker

编辑:我尝试在eclipse.ini上更改-Xms和-Xmx,但它仍然是相同的。 我有一个Java GUI程序,在事件触发时在后台运行繁重的计算。如果程序中的用户输入相当大(我认为不到200),一切运行顺畅 - 没有滞后,并且程序会给出并显示热图(这是我的输出)。但是,如果它确实是一个大数据,它开始滞后,有时,在整个过程的一半,程序冻结(例如300~724个数据)。请注意,例如,如果我说724数据,则表示我正在创建724个热图。

按钮点击触发GUI的主线程如下......

class ComponentVisualization implements Runnable{
    JScrollPane scrollPane;
    JPanel panelScroll;
    JPanel componentComboBoxPanel;
    @Override
    public void run(){
        scrollPane = new JScrollPane();
        panelScroll = new JPanel();
        panelScroll.setBorder(new EmptyBorder(10, 10, 10, 10));
        panelScroll.setLayout(new BoxLayout(panelScroll, BoxLayout.Y_AXIS));
        componentComboBoxPanel = new JPanel();
        componentComboBoxPanel.setMaximumSize(new Dimension(600, 25));
        componentComboBoxPanel.setLayout(new BoxLayout(componentComboBoxPanel, BoxLayout.X_AXIS));
        JLabel componentLabel = new JLabel("Component Plane Option: ");
        componentComboBoxPanel.add(componentLabel);
        JComboBox<String> componentComboBox = new JComboBox<String>();          
        componentComboBoxPanel.add(componentComboBox);
        for(int i = 0; i < optimalMaps.length; i++){
            componentComboBox.addItem(optimalMaps[i].getTypeOfData());
            optimalMaps[i].initComponentPlanes();   
        }

        JPanel outerPan = new JPanel();
        outerPan.setLayout(null);
        java.awt.event.ItemListener itemListener = new java.awt.event.ItemListener() {
          public void itemStateChanged(java.awt.event.ItemEvent itemEvent) {
              if (itemEvent.getStateChange() == java.awt.event.ItemEvent.SELECTED) {
                  int indexSelected = componentComboBox.getSelectedIndex();
                  System.out.println("ind:" + indexSelected);
                  outerPan.removeAll();
                  for(int i = 0; i < optimalMaps[indexSelected].getComponentPlanes().length; i++){
                    JPanel pan = new JPanel () ; 
                    pan.setLayout(null);
                    pan.add(optimalMaps[indexSelected].getComponentPlanes()[i]);
                    pan.setBorder(javax.swing.BorderFactory.createTitledBorder(
                            optimalMaps[indexSelected].getInputData().getVariableLabels()[i]));
                    pan.setBounds(240*(i%4),(280*(i/4)),240,280);
                    pan.setToolTipText(optimalMaps[indexSelected].getInputData().getVariableLabels()[i]);
                    outerPan.add(pan);
                  }
                  outerPan.setPreferredSize(new Dimension(240*4, 280*(optimalMaps[indexSelected].getSOMTrainer()
                          .getLattice().getNumberOfNodeElements()/4 + 1)));

                  outerPan.revalidate();
                  outerPan.repaint();
               }
          }
        };
        componentComboBox.addItemListener(itemListener);
        panelScroll.add(componentComboBoxPanel);
        panelScroll.add(outerPan);
        componentComboBox.setSelectedIndex(-1);
        componentComboBox.setSelectedIndex(0);  
        //return null;
        done();
    }
    protected void done(){
        scrollPane.setViewportView(panelScroll);
        for(int i = 0; i < finalVisualizationTabPane.getTabCount(); i++){
            if(finalVisualizationTabPane.getTitleAt(i).equals("Component Planes"))
                finalVisualizationTabPane.remove(i);
        }
        finalVisualizationTabPane.add("Component Planes", scrollPane);
        finalVisualizationTabPane.setSelectedIndex(finalVisualizationTabPane.getTabCount() - 1);
        finalVisualizationPanel.revalidate();
        finalVisualizationPanel.repaint();
        componentDone = true;
        visLogger.throwSuccessMessage("Component Planes Visualization completed! \n");
    }   
}

我尝试过使用SwingWorker而不是传统的Thread,但它几乎是一样的。它在中途停留了大量的LAGS和FREEZES。

这是由&#34; optimalMaps [i] .initComponentPlanes();&#34;触发/调用的代码。来自上面的代码

public void initComponentPlanes(){
    componentPlanes = new ComponentPlane[somtrainer.getLattice().getNumberOfNodeElements()];
    int size = somtrainer.getLattice().getNumberOfNodeElements();
    for(int i = 0; i < size; i++){
        System.out.println(i + ": " + inputData.getVariableLabels()[i] + " size : " + size);
        componentPlanes[i] = new ComponentPlane(somtrainer.getLattice(), i);
        componentPlanes[i].setBounds((240 - 225)/2, (280-240)/2, 225, 240);
        componentPlanes[i].setOrigMaxMin(maxMin[i][0], maxMin[i][1]);
        //if(i % 100 == 0) System.gc();
    }
}

我还会向您展示ComponentPlane.class。我也尝试使ComponentPlane.class成为一个可运行的类,并尝试在上面的代码中使用componentPlanes [i] .run()但产生几乎相同的结果。 这是组件类的代码

public class ComponentPlane extends JPanel{
private Lattice lattice;
private int componentNumber;
private double minValue;
private double maxValue;
private double origMinValue;
private double origMaxValue;

public ComponentPlane(Lattice lattice, int componentNumber){
    this.lattice = new Lattice();
    this.componentNumber = componentNumber;
    initLattice(lattice);
    initComponentPlane();
}

private void initLattice(Lattice lattice){
    this.lattice.setLatticeHeight(lattice.getLatticeHeight());
    this.lattice.setLatticeWidth(lattice.getLatticeWidth());
    this.lattice.setNumberOfNodeElements(lattice.getNumberOfNodeElements());
    this.lattice.initializeValues();
    for(int i = 0; i < this.lattice.getTotalNumberOfNodes(); i++){
        this.lattice.getLatticeNode()[i] = new Node(lattice.getLatticeNode()[i]);
    }

    this.lattice.setNodeHeight(lattice.getNodeHeight());
    this.lattice.setNodeWidth(lattice.getNodeWidth());
    this.lattice.setTotalNumberOfNodes(lattice.getTotalNumberOfNodes());

}

public Lattice getLattice(){
    return lattice;
}

private void initComponentPlane(){
    maxValue = lattice.getLatticeNode()[0].getDoubleElementAt(componentNumber);
    minValue = lattice.getLatticeNode()[0].getDoubleElementAt(componentNumber);

    for(int i = 1; i < lattice.getTotalNumberOfNodes(); i++){
        if(lattice.getLatticeNode()[i].getDoubleElementAt(componentNumber) < 
                minValue){
            minValue = lattice.getLatticeNode()[i].getDoubleElementAt(componentNumber); 
        }
        if(lattice.getLatticeNode()[i].getDoubleElementAt(componentNumber) > maxValue){
            maxValue = lattice.getLatticeNode()[i].getDoubleElementAt(componentNumber);
        }
    }
    for(int i = 0; i < lattice.getTotalNumberOfNodes(); i++){
        Node currNode = lattice.getLatticeNode()[i];
        int colorValue = (int)Math.round((currNode.getDoubleElementAt(componentNumber)
                - minValue) / (maxValue - minValue) * 1020);
        Color nodeColor = new Color(0);
        int caseValue = colorValue/256;

        if(caseValue == 0)
            nodeColor = new Color(0, (colorValue % 256), 255);
        else if(caseValue == 1)
            nodeColor = new Color(0, 255, 255 - (colorValue % 256));
        else if (caseValue == 2)
            nodeColor = new Color((colorValue % 256), 255, 0);
        else nodeColor = new Color(255, 255 - (colorValue % 256), 0);

        lattice.getLatticeNode()[i].setNodeColor(nodeColor);
    }
}

public double getMaxValue(){
    return maxValue;
}

public double getMinValue(){
    return minValue;
}

public void setOrigMaxMin(double maxValue, double minValue){
    this.origMaxValue = this.maxValue * (maxValue - minValue) + minValue;
    this.origMinValue = this.minValue * (maxValue - minValue) + minValue;
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    g2.scale(0.5, 0.5);

    for(int i = 0; i < lattice.getTotalNumberOfNodes(); i++){
        g.setColor(lattice.getLatticeNode()[i].getNodeColor());
        g.fillRect(lattice.getLatticeNode()[i].getxPos() - lattice.getNodeWidth() /2, 
                lattice.getLatticeNode()[i].getyPos() - lattice.getNodeHeight() /2
                , lattice.getNodeWidth(), lattice.getNodeHeight());
        g.setColor(Color.BLACK);
        g.drawRect(lattice.getLatticeNode()[i].getxPos() - lattice.getNodeWidth() /2, 
                lattice.getLatticeNode()[i].getyPos() - lattice.getNodeHeight() /2
                , lattice.getNodeWidth(), lattice.getNodeHeight());
    }

    g.setColor(Color.BLACK);
    double hund = 100;
    int intMaxValue = (int) (origMaxValue*hund);
    int intMinValue = (int) (origMinValue*hund);
    g.setFont(new Font("Arial", Font.PLAIN, 18));
    g.drawString(Double.toString(intMinValue/hund), 0, 470);
    g.drawString(Double.toString(intMaxValue/hund), 405, 470);

    for(int i = 0; i < 1024; i++){
        if(i < 256) g.setColor(new Color(0, (i % 256), 255));
        else if(i < 512) g.setColor(new Color(0, 255, 255 - (i % 256)));
        else if(i < 768) g.setColor(new Color((i % 256), 255, 0));
        else g.setColor(new Color(255, 255 - (i % 256), 0));
        double width = 350;
        g.fillRect((int)Math.ceil(i * width/1024) + 50, 455, (int)Math.ceil(width/1024), 15);
    }

    g.setColor(Color.BLACK);
    g.drawRect(50, 455, 350, 15);
}

}

另外,有时候,我在中途结束后等待太久后会收到此错误...     线程中的异常&#34;图像提取器0&#34; java.lang.OutOfMemoryError:Java堆空间     at java.awt.image.DataBufferInt。(DataBufferInt.java:75)     在java.awt.image.Raster.createPackedRaster(Raster.java:467)     at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1032)     at sun.awt.image.ImageRepresentation.createBufferedImage(ImageRepresentation.java:253)     at sun.awt.image.ImageRepresentation.setPixels(ImageRepresentation.java:559)     at sun.awt.image.ImageDecoder.setPixels(ImageDecoder.java:138)     at sun.awt.image.JPEGImageDecoder.sendPixels(JPEGImageDecoder.java:119)     at sun.awt.image.JPEGImageDecoder.readImage(Native Method)     at sun.awt.image.JPEGImageDecoder.produceImage(JPEGImageDecoder.java:141)     at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:269)     at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:205)     at sun.awt.image.ImageFetcher.run(ImageFetcher.java:169)

很抱歉这篇冗长的帖子。我迫切需要你的帮助。谢谢。

0 个答案:

没有答案