To be concise: don't put all your eggs into one basket. If you want shared class - write shared class.

Is there really need to allow shared objects different methods, and non-shared objects different methods? Why don't we separate implementation instead of methods according to being shared?

Exactly. Separate implementations. Completely. Shared is not just about "insert synchronized everywhere and be done with it". As a storage class, it tells the compiler "don't reorder accesses to this variable". Yes, as method attribute, it disallows you to call this method on an unshared reference. But that doesn't mean you now should rush to create both shared and non-shared methods for your classes: you'll be doing yourself a disservice. Design and implementation of concurrent data structures is very different from non-concurrent ones. Look up any concurrent data structure and see how drastically it differs from the plain, "single-threaded" one, even if it's built on lock-based synchronization, let alone lock-free. Providing two different implementations (that require different data for e.g. bookkeeping) inside one class is impractical and error-prone.

If you're just going to synchronize every single method call for your class on a mutex, then you don't really need shared qualifier at all (well, you'll need to briefly cast the reference to shared to e.g. pass it to another thread).

Also, I assume you understand that 'shared' and all its aspects are not yet fully realized in the language. Andrei mentioned that finalizing 'shared' should be made one of the primary goals. Maybe we would see some interesting syntactic solutions, type system improvements, etc. I think we already can help with some things (see e.g. my thread about shared sync primitives).

But regardless, design your single-threaded and concurrent data separately, go easy on yourself :)

Reply via email to