最近我一直用“ReentrantLock”重构我的项目以简化逻辑
一般的想法是:
1.“主”可运行线程自行运行
2.如果一切正常,主线程将在条件“nextStep”上等待
3.当发生错误时,方法“onCancel()”将被/在另一个线程中调用,迫使主线程抛出InterruptionExcpetion,因此关闭将发生
经过一些测试后,我发现了自己的方法:
doInterrupt();
从未按预期工作:强制主线程输入“InterruptedException”子句并退出循环。
UPDATE-2:
我已经向所有输出日志行添加了“被中断”的调试消息,如果结果中断状态被某个人“神秘地”清除了......
更新:
锁定和条件方法:
lock.lockInterruptibly();
condition.await();
似乎没有检查中断状态SOMETIMES? .... javadoc上写着:
...... If the current thread: has its interrupted status set on entry to this method; or is interrupted while acquiring the lock, then InterruptedException is thrown and the current thread's interrupted status is cleared. ......
[action] waiting for completion...: 1 [is-interrupted:false]
>> DEBUG ---> will begin next loop [is-interrupted:false]
[action] reset for next iteration: 2 [is-interrupted:false]
[action] cancelling... [is-interrupted:false]
>> DEBUG ---> will interrupt [is-interrupted:false]
>> DEBUG ---> check. [is-interrupted:true]
[action] waiting for completion...: 2 [is-interrupted:false]
>> DEBUG ---> will begin next loop [is-interrupted:false]
[action] reset for next iteration: 3 [is-interrupted:false]
[action] waiting for completion...: 3 [is-interrupted:false]
>> DEBUG ---> will begin next loop [is-interrupted:false]
[action] reset for next iteration: 4 [is-interrupted:false]
[action] waiting for completion...: 4
>> DEBUG ---> will begin next loop
[action] reset for next iteration: 5
[action] waiting for completion...: 5
>> DEBUG ---> will begin next loop
[action] reset for next iteration: 6
...... and so on until i == max
[info] main process has reached a finish state.
这基本上意味着中断信号丢失或不以某种方式处理...
有更好的方法吗?或至少修改我的代码逻辑?
任何多线程专家???
这是我的代码:
public class SBCSTaskEngine extends GenericEngine<SBCSTask> implements XListener {
private final ReentrantLock lock = new ReentrantLock();
private final Condition nextStep = lock.newCondition();
private volatile Thread main = null;
// something else ...
// it's a runnable "MAIN"
@Override
protected void run() {
try {
main = Thread.currentThread();
// some setting up... x is between 1 ~ 10000
for (int i = 1; i <= max; i++) {
lock.lockInterruptibly();
// some work ...
log("[action] waiting for completion...: " + i);
// a very long wait (could be REALLY fast if task went south)
nextStep.await();
if (max == i) {
isNormalCompletion = true;
} else {
log("[action] reset for next iteration:" + (i+1));
// some reset work...
}
lock.unlock();
} // end of [for] loop
} catch (InterruptedException e) {
log("[event] process stopped by singal.");
} finally {
try { lock.unlock(); } catch (Throwable ignored) {}
}
log("[info] main process has reached a finish state.");
}
private void doInterrupt() {
log(">> DEBUG ---> will interrupt");
if (main != null)
main.interrupt();
log(">> DEBUG ---> check.");
}
/**
* implement: XListener(series)
* instruct main process to enter cancel sequence
*
* known-issue: duplicate call? sync on method? wait for risk evaluation
*/
@Override
public void onCancel() {
log("[action] cancelling...");
doInterrupt();
}
/**
* implement: XListener(series)
* proceed the main thread to next loop
*
* known-issue: signal might occur before all "memebers" could await on the condition (happen-before?), just take the chance for now...
*/
@Override
private void doNotifyNextStep() {
try {
lock.lockInterruptibly();
log(">> DEBUG ---> will begin next loop");
nextStep.signalAll();
} catch (InterruptedException e) {
doInterrupt();
} finally {
try { lock.unlock(); } catch (Throwable ignored) {}
}
}
} // end of [SBCSTaskEngine] class
更多信息:我使用的Java版本:
java version "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03) Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
答案 0 :(得分:0)
仔细检查“process()”中使用的每一种方法后,结果发现有一种方法“吞下”InterruptionException意外...
简单地抛出异常,整个代码/类现在按预期工作~~~
非常感谢“@ hendalst”,他在我的帖子中评论过,让我修改所有可能的中断泄漏...正如你所说:“上面的代码工作”,根本原因的方法在评论区域内“//一些工作。 ..“我没有在这里张贴......
并感谢“@orionll”关于编码原则的建议