The debugging of multi-threaded programs is too much trouble, there is no way debug, all depends on log analysis, and the problems encountered last night were solved today.
July - I do a workflow project, the goal is to build a lightweight process service component.
Yesterday evening in the Type of the branch process in July, on the Join node activity, randomly inconsistent status changes. Our implementation logic is "End of Events -> Take the token to the Change -> Change Notice Next Activities -> A activity will make a card in the pre-change condition in the presence of the start condition, but it seems to be There are two pre-TRANSION TRANSITIONs of an AND JOIN activity that there is a notification of both the active state shift. The activity received two notifications is correct, but the status of changing the activity in the first notice should be not considered, and it is also this exposed synchronization problem for the modification of the active status. The management of the active status We use "july.dblab.jlu.StateMachine" is an automatic component we do. The problem appears inside it. When a thread is calling StateMachine.Transform, the current state of the state machine should be locked without the chance of the current state:
Void check () {
Synchronized (currentstate) {
IF (Tranform's Auto Condition Meet) {
Transformasyn (to);
}
}
}
Void Transform (state to) {
.....
Synchronized (currentstate) {
BeforestateChange ();
CurrentState = TO;
}
AfTerstateChange ();
.....
}
Void transformasyn (state to) {
New Thread to Call Transform;
}
The problem is in the function check () that checks the current state. It is called an asynchronous Transform method, so it is possible to call the CHECK () thread when the new Transform thread has not come yet and locked in the current state. Opened the lock of CurrentState, natural other threads have the opportunity to take advantage of it. In fact, the design requirements for StateMachine are also just determined automators, so there is only one change in CHECK, there is only one transform that calls asynchronous, so directly simultaneously call, there should be no problem.
Conclusion: Do not attempt to pass the lock with the newly generated thread in the synchronous method, which will leave the synchronous void, and the probability is quite high: because the construction of threads is relatively time consuming, in considerable cases of CHECK The thread will give up the lock first. There should be a better way.
So sleepy, written in a mess, have a work and change.