Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't this code deadlock?

I'm investigating a deadlock problem on setText but I need to first learn and understand about deadlocks. To this end I have created a short program to try and replicate what may be happening on the larger scale but I am unsure as to why my smaller program never deadlocks.

Here is my learning program:

public static void main(String[] a)
{
    JFrame frame = new JFrame();
    final JTextField p = new JTextField("start");

    JButton btn = new JButton("button");
    btn.addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run(){
                    p.setText(String.valueOf(System.nanoTime()));
                }
            });
        }
    });

    frame.getContentPane().setLayout(new FlowLayout());
    frame.getContentPane().add(p);
    frame.getContentPane().add(btn);
    frame.setSize(400, 400);
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

I thought that modifications to swing could not be done in a separate thread, so I have a setText to change the JTextField on a button click in a invokeLater. Doing so should break the single thread rule, would this not cause a deadlock?

like image 518
Aequitas Avatar asked Apr 18 '26 08:04

Aequitas


1 Answers

Making changes to Swing components from other threads won't deadlock your program (at least not usually)--it's just that the JVM isn't obligated to reflect changes to state made in one thread in other threads unless there's a happens-before relationship, such as a synchronized block or access to a volatile field. The JVM might decide to read a variable's value once and never reread it in the current thread, which would mean that your update would never get seen by the thread that's drawing the UI, or it might get around to updating it at some unpredictable later time.

Using invokeLater to insert the update into the EDT ensures that there's a happens-before between that setText and the next draw operation.

Update: As you've now succeeded in making the code deadlock by moving where you queue the Runnable, the problem is that the EDT isn't running yet when you try to queue the operation on it.

like image 124
chrylis -cautiouslyoptimistic- Avatar answered Apr 19 '26 22:04

chrylis -cautiouslyoptimistic-



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!