fixed "endless recursion in font" exception in FlatLaf$ActiveFont.createValue() if UIManager.getFont() is invoked from multiple threads (issue #456)

This commit is contained in:
Karl Tauber
2021-12-23 21:16:07 +01:00
parent efd8cf8236
commit 5b16a814c8
2 changed files with 34 additions and 1 deletions

View File

@@ -1223,6 +1223,9 @@ public abstract class FlatLaf
}
private Object getValue( Object key ) {
// use local variable for getters to avoid potential multi-threading issues
List<Function<Object, Object>> uiDefaultsGetters = FlatLaf.this.uiDefaultsGetters;
if( uiDefaultsGetters == null )
return null;
@@ -1276,8 +1279,9 @@ public abstract class FlatLaf
this.scaleSize = scaleSize;
}
// using synchronized to avoid exception if invoked at the same time on multiple threads
@Override
public Object createValue( UIDefaults table ) {
public synchronized Object createValue( UIDefaults table ) {
if( inCreateValue )
throw new IllegalStateException( "FlatLaf: endless recursion in font" );

View File

@@ -22,7 +22,9 @@ import java.util.Random;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLightLaf;
@@ -54,6 +56,7 @@ public class FlatStressTest
private JComponent createStressTest() {
return createComboBoxStressTest();
// return createGetFontStressTest();
}
// for https://github.com/JFormDesigner/FlatLaf/issues/432
@@ -80,4 +83,30 @@ public class FlatStressTest
return comboBox;
}
// for https://github.com/JFormDesigner/FlatLaf/issues/456
@SuppressWarnings( "unused" )
private JComponent createGetFontStressTest() {
JLabel label = new JLabel( "test" );
Runnable runnable = () -> {
for(;;) {
UIManager.getFont( "Label.font" );
}
};
Thread thread1 = new Thread( runnable);
thread1.setDaemon( true );
thread1.start();
Thread thread2 = new Thread( runnable);
thread2.setDaemon( true );
thread2.start();
Thread thread3 = new Thread( runnable);
thread3.setDaemon( true );
thread3.start();
return label;
}
}