JDK-4765261 : JTextArea.append does not follow spec (it is not ThreadSafe)
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-10-18
  • Updated: 2002-10-23
  • Resolved: 2002-10-23
Related Reports
Duplicate :  
Description

Name: sv35042			Date: 10/18/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
JTextArea.append says: This method is thread safe, however
it is not.

When running the code below the application hangs due to
JTextArea append not being thread safe.
(As this is a threading issue, depending on environment
breakpoints may be required to reproduce the problem,
however on my computer the code below reproduces the problem
some of the time without the need for breakpoints).

Cause:

 main Thread:
  JTextArea.append
  PlainDocument.insertString
                insertString --> writeLock()
                handleInsertString
                fireInsertUpdate
  BasicTextUI$UpdateHandler.insertUpdate
  BasicTextUI.modelChanged
              setView
  JTextArea.removeAll --> getTreeLock()

 AWT-EventQueue Thread:
  JViewport.paintChildren --> getTreeLock
  JTextArea.paint
            paintComponent
  BasicTextAreaUI.update
                  paint --> readLock

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. run code
2. if it doesn't hang, then breakpoints may be required:

easiest way that I found:
2 breakpoints in javax.swing.plaf.basic.BasicTextUI
- 1 in paint(Graphics, JComponent) doc.readLock()
- the other in setView(View) editor.removeAll()

play through breakpoints until they are at the points shown
above, then play through both of them.

Note the 1st few times the setView breakpoint is reached, it
is from within an instance of BasicTextAreaUI, play through
these until it is from within an instance of BasicTextUI as
shown above

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected: Application not to hang,
Actual: Application hangs

This bug can be reproduced occasionally.

---------- BEGIN SOURCE ----------
import java.text.*;
import java.util.*;
import javax.swing.*;

public class Test {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    final JTextArea ta = new JTextArea();
    frame.getContentPane().add(new JScrollPane(ta));
    frame.setSize(500,500);
    frame.setVisible(true);

    Locale[] locales = Locale.getAvailableLocales();
    for (int i = 0; i < locales.length; i++) {
      final Locale locale = locales[i];
      ta.append(locale + "\n");
      ta.append(NumberFormat.getCurrencyInstance(locale).format(5000L));
      ta.append(NumberFormat.getCurrencyInstance(locale).format(5000.5));
      ta.append(NumberFormat.getPercentInstance(locale).format(5000L));
      ta.append(NumberFormat.getPercentInstance(locale).format(5000.5));
      ta.append(NumberFormat.getIntegerInstance(locale).format(5000L));
      ta.append(NumberFormat.getIntegerInstance(locale).format(5000.5));
      ta.append(NumberFormat.getNumberInstance(locale).format(5000L));
      ta.append(NumberFormat.getNumberInstance(locale).format(5000.5));
      ta.append("\n");
    }
  }
}
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
use SwingUtilities.invokeLater wherever JTextArea.append is
done
(Review ID: 148284) 
======================================================================