4
votes

A common multi-threaded implementation is to have some class where Method_A() is running in a thread and sits blocked waiting for some signal/event member variable (e.g. WaitForSingleObject).

Interacting classes running in different thread will then call Method_B() which does some work, sets the signal/event variable, perhaps does some more work, then returns.

How do I represent this interaction on a Sequence Diagram?

Should I have two lifelines, one for each thread, even though they are operating on the same instance of the class? My modelling tool (Enterprise Architect 12) doesn't allow the same class to appear twice on a Sequence Diagram, so seems to discourage this.


Edit: Geert has noted that the Sequence Diagram should use instances, not classes, which is a fair comment. However the problem is the same: multiple lifelines would imply multiple instances, but in the question Method_A() and Method_B() are operating on the same instance, just from different threads. How can that be represented?

4
If you just draw it, it will become obvious.qwerty_so
Sadly not @ThomasKilian. I've been trying to get something sensible modelled for several hours now. Multiple lifelines for the same instance seems like the only way to get what I want.GrahamS

4 Answers

4
votes

The approach I have decided to take is to add two lifelines for the same instance, then label one lifeline with the <<thread>> stereotype and add the thread it runs in to the name:

My attempt at multi-threaded Sequence Diagram

I realise this is probably not standard UML, but it seems to get across all the information I want to express in a clear manner, which is the most important thing, right?

Martin Fowler does mention a few times in his book that sometimes a non-normative diagram is actually clearer. So that's my excuse. :)

2
votes

You should never use classes in sequence diagrams, but instead use instances/lifelines that have your class as classifier.

If you hold the control down when dragging a class to a sequence diagram you can choose to drop is as instance instead of as class.

This way you can add as many as you want for the same class.

2
votes

(Edit You can solve it by just using asynchronous messages as @sim points out. That will just do. The answer below is showing what is going on under the hood. So if you don't care about the details, go with that answer.)

You are asking more a design than an UML question. Namely, how do concurrent instances talk to each other. You said first

Method_A() is running in a thread and sits blocked waiting

which simply means that it can not accept anything since it is blocked. Now, guessing from the context of your question, I assume that you still want to communicate with that instance since

in different thread will then call Method_B()

So, in order to be able to accept a message the instance must be in an appropriate state. There are a couple of ways to achieve that. One simple is, if the according OS has support for that, to return to the scheduler and tell him that it's waiting for some message.

enter image description here

Now when method_b is being called you know inside Object1 that you are in some kind of idle state inside method_a and do appropriate (return-) action.

Another way would be to poll the scheduler for incoming messages and handle them.

You need to keep in mind that sending a message usually not directly deals with the instance but tells the system scheduler to interact with the appropriate instance (at least in most OSs).

I just remember from the Modula2 compiler I once wrote that it has a concept of coroutines which allows a concurrent thread to run within the compiled code. But basically that is just mapped to two independent threads running under the hood of a semi-single one and you'd depict that with two life-lines when going into detail.

N.B.: Rather than method it should be operation (since that is was is invoked by a message; while the method is what is implemented inside the operation). And as per common convention they should start with a lower case char.

And also: do NOT use classes in a SD. Unfortunately EA still allows that (why? Ask them!). Somewhere hidden in their docs there is a sentence that you must use instances. Else the model will break. A SD is always (!) a sample sequence of instances talking to each other. Classes do not talk, they are just blueprints for the instances.

2
votes

The notation you are looking for is an asynchronous message. You could theoretically express this using a single lifeline. But this wouldn't be readable. So a possibility would be having two instances of a threadclass in your class and show the interaction between the instances. But never show classes in a sequence diagram. But why are you using a sequence diagram at all? For such internal behavour an activity diagram is most likely more appropriate. There you can use send and receive messages elements to express such a behavour per thread. Or if it shall be shown in one diagram, you can use fork.