Runnable inside synchronized (this) 导致应用程序崩溃
Runnable inside synchronized (this) leads to app crash
我的代码是:
@Override
public void loadingDone(int whatIsDone) {
if (interrupt) {
return;
}
synchronized (this) {
// 1 - loaded with visu
// 2 - loaded without visu
switch (whatIsDone) {
case 1: // view.setLoading(true);
if (!view.isLoading()) {
//view.setStatusLineMsg(msg);
}
break;
case 3:
view.getParent().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
if ( view != null && view.isPmiUseModelviewAtStartup() ) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
view.changeModelViewBySUModelViewRegex();
}
}
});
view.setLoading(true);
// other code
case 4: // other code
default:
case 2:
view.setLoading(true);
break;
}
}
}
在 case 3
中,方法 view.changeModelViewBySUModelViewRegex()
调用另一个方法:
public Long[] getReferenceIdsColumn()
{
Long[] ret = null;
System.out.println("TreeDataItem.getReferenceIdsColumn()->"
+ "Object referenceIds = TCA3DNKernel.getModelItemAttrValue(getModelId(), getId(), TCA3DNModelDataColumn.ReferenceIdsColumn)");
Object referenceIds = TCA3DNKernel.getModelItemAttrValue(getModelId(), getId(), TCA3DNModelDataColumn.ReferenceIdsColumn);
//System.out.println("TreeDataItem.getReferenceIdsColumn(->if (referenceIds != null))");
if (referenceIds != null)
{
if (referenceIds instanceof Long[])
{
ret = (Long[]) referenceIds;
}
}
return ret;
}
应用程序在 运行 时崩溃:Object referenceIds = TCA3DNKernel.getModelItemAttrValue(getModelId(), getId(), TCA3DNModelDataColumn.ReferenceIdsColumn)
。 getModelItemAttrValue
是用 C++ 代码编写的。
我可以通过增加 case 3
中的线程休眠来解决这个问题,所以代码(java 或 C++)应该没有问题,但是线程同步的问题?如果我在调试时使用断点,似乎线程有时间完成任务并且应用程序不会崩溃。无论如何,这绝对是令人毛骨悚然的解决方案:
if ( view != null && view.isPmiUseModelviewAtStartup() ) {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
view.changeModelViewBySUModelViewRegex();
}
截图:
如有更好的解决方案,我将不胜感激!
似乎,同步的而不是 asyncExec 有帮助:
case 3:
view.getParent().getDisplay().syncExec(new Runnable() {
//code
}
我的代码是:
@Override
public void loadingDone(int whatIsDone) {
if (interrupt) {
return;
}
synchronized (this) {
// 1 - loaded with visu
// 2 - loaded without visu
switch (whatIsDone) {
case 1: // view.setLoading(true);
if (!view.isLoading()) {
//view.setStatusLineMsg(msg);
}
break;
case 3:
view.getParent().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
if ( view != null && view.isPmiUseModelviewAtStartup() ) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
view.changeModelViewBySUModelViewRegex();
}
}
});
view.setLoading(true);
// other code
case 4: // other code
default:
case 2:
view.setLoading(true);
break;
}
}
}
在 case 3
中,方法 view.changeModelViewBySUModelViewRegex()
调用另一个方法:
public Long[] getReferenceIdsColumn()
{
Long[] ret = null;
System.out.println("TreeDataItem.getReferenceIdsColumn()->"
+ "Object referenceIds = TCA3DNKernel.getModelItemAttrValue(getModelId(), getId(), TCA3DNModelDataColumn.ReferenceIdsColumn)");
Object referenceIds = TCA3DNKernel.getModelItemAttrValue(getModelId(), getId(), TCA3DNModelDataColumn.ReferenceIdsColumn);
//System.out.println("TreeDataItem.getReferenceIdsColumn(->if (referenceIds != null))");
if (referenceIds != null)
{
if (referenceIds instanceof Long[])
{
ret = (Long[]) referenceIds;
}
}
return ret;
}
应用程序在 运行 时崩溃:Object referenceIds = TCA3DNKernel.getModelItemAttrValue(getModelId(), getId(), TCA3DNModelDataColumn.ReferenceIdsColumn)
。 getModelItemAttrValue
是用 C++ 代码编写的。
我可以通过增加 case 3
中的线程休眠来解决这个问题,所以代码(java 或 C++)应该没有问题,但是线程同步的问题?如果我在调试时使用断点,似乎线程有时间完成任务并且应用程序不会崩溃。无论如何,这绝对是令人毛骨悚然的解决方案:
if ( view != null && view.isPmiUseModelviewAtStartup() ) {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
view.changeModelViewBySUModelViewRegex();
}
截图:
如有更好的解决方案,我将不胜感激!
似乎,同步的而不是 asyncExec 有帮助:
case 3:
view.getParent().getDisplay().syncExec(new Runnable() {
//code
}