I'm thinking about how one would go about designing a descriptive concurrency model for an OOP language that helps simplify concurrency scenarios for programmers (no easy task, concurrency is hard).

I've read a bunch about software transactional memory, the actor model, immutability etc etc but they don't exactly seem to offer an easy model either, and while functional programming is great for some concurrency and parallel scenarios some times you simply need to mutate some kind of state. While locking is considered bad by some atleast it's fairly easy to reason about on a basic level (until you get into deadlock territory that is)

Anyways, one of the ways I thought programmers could somewhat easier handle multi-threaded scenarios was that each class is responsible for it's own thread-safety on a per method/property basis. Ie other classes can only access properties and methods, they can't really lock on anything specifically, nor should they have to.

One way to make it easier though would be to annotate methods and properties for concurrency with their indent rather than locking specifics. The compiler will then try to deduce the most performing lock from that. So assuming atomicity what do you think good annotations would be? and what are potential problems with this approach,

I'm aware that it can't solve all scenarios (like transactions) but it should help the compiler enforce the programmers intent, and might even be able to warn on potential deadlock/racing scenarios

Here's some of the attributes i thought of so far (also note that none of them are mandatory but strictly compiler "hints")

<property preference="none|read|write|fair">

   <get access="free|exclusive|shared" 

    <set access="free|exclusive|shared|upgradeable" 
       duration="unknown|nano|brief|long" />


So for instance if get and set was set to shared access you might end up with an reader-writer lock. (do I need an attribute to control visiblity.) If duration for a write was set to nano perhaps it would use a spinlock. If there are many reads and few writes perhaps the compiler would use a different lock that if there were many writes and few reads etc etc.

Methods can be coupled into read/write pairs similarly to properties (in case you need more than one parameter).

For numeric properties that typically update based on some condition of it's value I was also thinking that instead of passing just a new value, you could pass an operator and an amount. That way you could lock, calculate the new value, see if it meets some internal condition and in that case update.

Anyways, I'm struggling a bit coming up with good attributes/notations that are somewhat easy for a programmer to wrap their head and reason about, any help and feedback deeply appreciated.

Sorry for the long rant, as I said this isn't an easy topic :)

  • Are you talking about this? en.wikipedia.org/wiki/Monitor_(synchronization) – S.Lott Apr 7 '11 at 22:43
  • 3
    Congratulations, you've rediscovered that concurrency is hard and locks aren't a very good solution. Locking is fairly easy to reason about until it becomes incredibly difficult to reason about. The problem is that this usually happens abruptly, without warning, and far earlier than you expected it to. – Rein Henrichs Apr 7 '11 at 23:17
  • You would have to guarantee that the compiler did exactly what you wanted all the time and never created deadlocks. I am not even sure that is possible, but I won't count it out. This biggest disadvantage that I see is that it would be possible that the locking configuration changes under the hood as the program evolves or is modified. This not really desirable from a maintenance or product development standpoint. Design decisions such as these should be deterministic. I think that this would actually make development harder not easier. – Pemdas Apr 8 '11 at 1:06
  • Pemdas, the kind of lock should probably be determistic but performance optimization could be done by the compiler, perhaps it could even be profiled with typical data to see how it's typically used and optimized around that. – Homde Apr 8 '11 at 5:19
  • what exactly does it mean to optimize locking performance? – Pemdas Apr 8 '11 at 14:55

The problem with locking is that--by definition--it doesn't scale. Only one thread can lock a data structure at a time.

A better solution to concurrency is generally the actor model, or some variant thereof. That is, share state by passing messages, not by locking. Erlang is an obvious example of that paradigm, but if you don't like functional languages then you might want to check out Google's Go, which is a procedural language that implements a similar message-passing mechanism (called channels, in combination with its lightweight threads, called goroutines).

  • That's kinda a blanket statement, there's plenty of programs that does just fine with some kind of locking. Sure exlusive locking isn't good but good reader-writer locks can perform quite well. I'm interested in the actor model though. I don't see how certain scenarios perform better under it though, if you use some form of concurrent queue for both read and write messages that might be eaier to reason about, but not necessarily perform better... – Homde Apr 8 '11 at 5:17
  • some interesting read: sics.se/~adam/pt/duality78.pdf – Homde Apr 8 '11 at 5:28

MS already added helpers for auto-parallelism to .NET. http://msdn.microsoft.com/en-us/library/dd460693.aspx

Certain concurency problems still need to be dealt with like file locks, but memory isnt an issue AFAIK. Workflow foundation has it too. Once again, theres some limits and it can get pretty hairy. If you search MS forums on workflow with my name you can find some examples of the nastiness.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.