gpt4 book ai didi

java - 与日志框架相关的特殊死锁

转载 作者:行者123 更新时间:2023-12-01 22:03:09 41 4
gpt4 key购买 nike

我有一个基于 GUI 的应用程序,它接收一个文件并以表格格式将其显示给用户,以列注释和一堆参数的形式获取一些输入。然后它相应地解析文件并启动“分析”。

我刚刚发现了一个死锁,这是我以前从未遇到过的。

Found one Java-level deadlock:
=============================
"RMI TCP Connection(5)-130.235.214.23":
waiting to lock monitor 0x00007fac650875e8 (object 0x0000000793267298, a java.util.logging.ConsoleHandler),
which is held by "AWT-EventQueue-0"
"AWT-EventQueue-0":
waiting to lock monitor 0x00007fac65086b98 (object 0x00000006c00dd8d0, a java.io.PrintStream),
which is held by "SwingWorker-pool-1-thread-3"
"SwingWorker-pool-1-thread-3":
waiting to lock monitor 0x00007fac65087538 (object 0x00000006c001db48, a java.awt.Component$AWTTreeLock),
which is held by "AWT-EventQueue-0"

本质上存在解析错误,尝试记录它会导致应用程序完全挂起。有趣的是,在该特定步骤之前和之后,日志记录似乎正常工作。

以下是与分析任务相关的代码部分:

    // Activate progress indicator
frame.getMainFrame().activateInfiGlass();

SwingWorker<Map<Analyte,AnalysisResult>, Void> worker = new SwingWorker<Map<Analyte,AnalysisResult>, Void>() {
@Override
protected Map<Analyte,AnalysisResult> doInBackground() {
try {
// register parameters
param.addParam(AnalysisParams.value_key,descPanel.getValueTypeComboIndex());
param.addParam(AnalysisParams.sepchar_key,descPanel.getSepCharComboIndex());
paramPanel.registerParams();

StringBuilder sb = new StringBuilder("Data preview completed, initiating analysis...");
sb.append(System.lineSeparator())
.append("... column annotations: ")
.append(Arrays.toString(annots));
logger.info(sb.toString() + System.lineSeparator());

// Create dataset; to be passed on to SwingWorker which will
// execute the analysis
ds = new Dataset();

String[] line;
for (int i=0; i < data.length; i++){
line = data[i];
// If ignore button is clicked, skip row..
if(!(Boolean) table.getValueAt(i, 0))
ds.addRow(line, annots); // <-- This step is where the parsing exception occurs
}

System.out.println("Dataset parsed...");
logger.info("Dataset parsing complete "
+ System.lineSeparator()
+ ds.toString()
+ System.lineSeparator());

visualizeDataset();
conserv = new ConcurrencyService(ds, dbMan);
conserv.serve();

} catch (InterruptedException e) {
logger.severe("Concurrency service interrupted"
+ System.lineSeparator()
+ DebugToolbox.getStackTraceAsString(e)
+ System.lineSeparator());
System.err.println("Interrupt exception!!");
}
return conserv.getAnalyzedPaths();
}

@Override
protected void done() {
try{
results = get();
visualizeResults();
}
catch (InterruptedException ignore) {}
catch (java.util.concurrent.ExecutionException e) {
String why = null;
Throwable cause = e.getCause();
if (cause != null) {
why = cause.getMessage();
} else {
why = e.getMessage();
}
System.err.println("Error analysing data: " + why);
} catch (SQLException e) {
e.printStackTrace();
}

logger.info("#DEBUG: Conserv should have been terminated by now..." + System.lineSeparator());
frame.getMainFrame().deactivateInfiGlass();
DebugToolbox.stopExecTimer();
}
};
worker.execute();
}});

使用方法 addRow()Dataset 实例中对值进行解析。下面这段代码展示了解析错误的处理方式

public double valueToIntensity(String val){
if(val.equalsIgnoreCase(""))
return missingVal;

try{
double d = Double.parseDouble(val);
switch(valType){
case RAW: break;
case LOG2: d = StrictMath.pow(2,d); break;
case LOGN: d = StrictMath.pow(StrictMath.E, d); break;
case LOG10: d = StrictMath.pow(10,d); break;
default: throw new RuntimeException("Unrecognized value type");
}

if(Double.isInfinite(d)){
StringBuilder msg = new StringBuilder("Double precision overflow occurred: 'd' is infinite!!");
msg.append(System.lineSeparator())
.append("chosen value scale is ").append(valType)
.append(System.lineSeparator())
.append("value = ").append(val);

logger.severe(msg.toString() + System.lineSeparator());

System.err.println("Data parsing error!!" +
"Please make sure that you have selected the correct scale...");
System.exit(FeverMainFrame.exitCodes.get(this.getClass()));
}
else
return d;

} catch (NumberFormatException e){
System.err.println("Data parsing error!!");
// THE FOLLOWING LINE IS WHERE DEADLOCK OCCURS
logger.severe("Expected: string representation of a numerical value, "
+ "Found: " + val + System.lineSeparator());
System.err.println("Please make sure the datafile does not include any strings "
+ "like 'N/A' or '-' for denoting missing values.");


System.exit(FeverMainFrame.exitCodes.get(this.getClass()));
}

// TODO: This should never happen!
throw new RuntimeException("Assertion failed during dataset parsing...");
}

如果我删除导致解析错误的值,而不更改任何其他内容,则日志记录框架和应用程序的其余部分都会按预期运行。

如果您能了解此特定案例中发生的情况,我将不胜感激。

最佳答案

如果没有完整的示例,请验证您的 doInBackground() 实现不会尝试更新任何 GUI component or model 。相反,publish() 临时结果并在 EDT 可用时 process() 它们。显示了完整的示例 here .

关于java - 与日志框架相关的特殊死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33343577/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com