processing / processing/processing4
nf/nfc do not seem to be threadsafe and throw NullPointerException
还没有人认领这个 Issue。
- 主要语言
- Java
- 星标
- 494
- 派生
- 183
- 平均合并
- 4 小时 39 分钟
- 30 天内合并 PR
- 3
描述
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.
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 processing.core.PApplet 中堆栈跟踪所示的 nf 调用开始,然后检查相关的 nf 和 nfc 格式化路径及其 NumberFormat 状态。使用 nf(float, int, int)、nf(int, int) 和 nfc(float, int) 反复运行多线程复现;当并发执行不再产生所报告的 NullPointerException 或 StackOverflow 时,即表示完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- java
- 领域
- api
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 45/100