Open
Description
Most appropriate sub-area of Processing 4?
Core/Environment/Rendering
Processing version
3 to current
Operating system
Linux
Steps to reproduce this
"1. Create a method calling nf(float, int, int), nf(int, int), nfc(float, int)
-
Run this method within a thread
thread("myFunction")
. -
Let it run for a longer time"
This is a little bit harder to reproduce and I only got it first with a complex project.
After a while you will end up with either a Stackoverflow or NullPointerException like this.
java.lang.NullPointerException: Cannot assign field "fastPathContainer" because "this.fastPathData" is null
at java.base/java.text.DecimalFormat.resetFastPathData(DecimalFormat.java:1157)
at java.base/java.text.DecimalFormat.checkAndSetFastPathStatus(DecimalFormat.java:1081)
at java.base/java.text.DecimalFormat.fastFormat(DecimalFormat.java:1659)
at java.base/java.text.NumberFormat.format(NumberFormat.java:327)
at processing.core.PApplet.nf(PApplet.java:10108)
at core3.app.gui.GUIInfo.pre(GUIInfo.java:413)
at jdk.internal.reflect.GeneratedMethodAccessor24.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1436)
at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1429)
at processing.core.PApplet.handleMethods(PApplet.java:1628)
at processing.core.PApplet.handleDraw(PApplet.java:2473)
at processing.opengl.PSurfaceJOGL$DrawListener.display(PSurfaceJOGL.java:866)
at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:759)
at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:452)
at com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:178)
at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
at java.base/java.util.TimerThread.run(Timer.java:516)
snippet
Additional context
Doing a little bit research, the NumberFormat in nf/nfc seems not to be thread safe. General consent on this seems to be to use a ThreadLocal. So modifying PApplet like this, seems to fix it.
private static final ThreadLocal<NumberFormat> threadLocalIntNf = ThreadLocal.withInitial(() -> {
NumberFormat nf = NumberFormat.getInstance();
nf.setGroupingUsed(false); // no commas
nf.setMinimumFractionDigits(0);
nf.setMaximumFractionDigits(0);
return nf;
});
static public String nf(float num, int left, int right) {
// if ((float_nf != null) &&
// (float_nf_left == left) &&
// (float_nf_right == right) &&
// !float_nf_commas) {
// return float_nf.format(num);
// }
float_nf = threadLocalIntNf.get();
float_nf.setGroupingUsed(false);
float_nf_commas = false;
float_nf.setMinimumIntegerDigits(left);
float_nf.setMinimumFractionDigits(right);
float_nf.setMaximumFractionDigits(right);
return float_nf.format(num);
}
Would you like to work on the issue?
I can provide my fix, but it needs some optimisation/cleanup.