An elegant way to make your JDK8 code irresponsive

This is a simple example where new API and modern implementation allow write irresponsive GUI.

Anyone who has been starting to learn JDK8 Stream API sees a lot of advertisements how elegant Stream API is.Anyone is informed about a parallel() method which wisely distribute you calculations among cores (if your functions are pure, of course). But a junior programmer may not realise how dangerous this API could be.

The code below shows how to hang you UI even without running anything dangerous on the EDT thread. Run the example, notice that a part of the window is constantly changing its colour, press the button.

Test to illustrate parallel streams and Swing UI issue

After a short delay you frame will become irresponsive. The problem is in the parallel() call. Comment it out and the UI becomes alive. Of course, you may need to specify greater heap for such a big List (for instance  with -Xmx4g argument).


public class HangJavaGUIFromNonEDTThread {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame test = new JFrame("Test");

            List<Integer> listOfIntegers = IntStream.generate(() -> ThreadLocalRandom.current().nextInt(10))
                                                    .limit(100000000)
                                                    .boxed()
                                                    .collect(Collectors.toList());

            test.setLayout(new GridBagLayout());
            JButton jButton = new JButton(new AbstractAction("Calculate") {
                @Override
                public void actionPerformed(ActionEvent e) {
                    new Thread() {
                        @Override
                        public void run() {
                            System.err.println(listOfIntegers.parallelStream().filter(i -> i < 5).count());                             SwingUtilities.invokeLater(() -> setEnabled(true));
                        }
                    }.start();
                    setEnabled(false);
                }
            });
            test.add(jButton);

            Dimension panelSize = new Dimension(200,200);

            Color [] colors = {
                    Color.green,
                    Color.red,
                    Color.yellow,
                    Color.blue
            };

            Random random = new Random();

            JPanel jPanel = new JPanel() {
                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.setColor(colors[random.nextInt(colors.length)]);
                    g.fillRect(0, 0, panelSize.width, panelSize.height);
                }
            };

            jPanel.setPreferredSize(panelSize);

            Timer timer = new Timer(100, e -> jPanel.repaint());

            timer.start();

            test.add(jPanel);

            test.pack();
            test.setVisible(true);

        });
    }
}

Andrew Krasny noted, that “this effect is not related to the threads used. This is a GC problem – button hit triggers the Full GC and.. the whole word stops – can see this easily – java -XX:+PrintGCDetails -XX:+PrintGCDateStamps ….”

2016-08-05T21:42:44.514-0300: [GC (Allocation Failure) [PSYoungGen: 58273K-&gt;1488K(76288K)] 58273K-&gt;17520K(251392K), 0.0330779 secs] [Times: user=0.22 sys=0.00, real=0.03 secs] 
2016-08-05T21:42:50.197-0300: [GC (Allocation Failure) [PSYoungGen: 67024K-&gt;2513K(141824K)] 1206960K-&gt;1142458K(1306624K), 0.8698558 secs] [Times: user=6.48 sys=0.05, real=0.87 secs] 
2016-08-05T21:42:51.067-0300: [Full GC (Ergonomics) [PSYoungGen: 2513K-&gt;0K(141824K)] [ParOldGen: 1139944K-&gt;413111K(598528K)] 1142458K-&gt;413111K(740352K), [Metaspace: 9953K-&gt;9953K(1058816K)], 16.2868371 secs] [Times: user=20.38 sys=0.21, real=16.29 secs] 

“See – on my PC this takes 20 seconds!

Try to add System.gc(); just before making the form visible – you’ll see the pause on startup, but the button will work fine later.

BTW, Zing has no this problem ;)”

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>