Synchronizing Java Streams in C #
I am a Java programmer and I know a few things about streaming int Java.
In Java, I can block a method using a synchronized keyword:
private int a;
private int b;
private int c;
private synchronized void changeVars()
{
a = 4;
b = 2;
c = a+b;
}
I searched in msdn and saw that there are several toys in C # to play with threads. For example, monitor.Enter, monitor.Exit, lock, or extended mutex.
But I need to sync one method. What's the equivalent to it in C #?
Thanks in advance.
source to share
The direct equivalent of this is using lock (this):
private void ChangeVars()
{
lock (this) {
a = 4;
b = 2;
c = a+b;
}
}
or indeed using MethodImplAttribute as described by R. Bemrose, which amounts to the same thing:
[MethodImpl(MethodImplOptions.Synchronized)]
private void ChangeVars()
{
a = 4;
b = 2;
c = a+b;
}
... however, it is not recommended to use a publicly visible object for a lock, as someone else might decide to use it as a lock object as well, so a better translation would be:
private object monitor = new object();
private void ChangeVars()
{
lock (monitor) {
a = 4;
b = 2;
c = a+b;
}
}
source to share
Just to be clear - declaring a method synchronized in Java requires the caller to contain a monitor on the object that the method was called on (which is an object Class
for static methods).
So to say that you can "block a method" is misleading because you do not completely block this method (the same method can still be called on different instance objects), and you block more than this method (no other bit of code that requires that the target monitor, including other synchronized methods or explicit acquisitions, can run concurrently).
Synchronization is tough , and ideally you need to know more than "a few things" about it if you want to avoid deadlocks and visibility issues that almost never show up during testing, or facilitate debugging. Assuming a possibly incomplete understanding of synchronization in one language, and trying to port it to another language with different primitives and probably a different memory model is a recipe for disaster.
So, while this is not the answer to the one liner you were looking for, I will argue that any answer to one liner is doomed to fail without knowing the entire ecosystem to support it. So you should read a good book / tutorial on Synchronization in C # and not try to translate the Java keyword by keyword.
source to share
The preferred solution is to wrap the method body in an expression lock
.
internal class Foo
{
private Object lockObject = new Object();
private void ChangeVars()
{
lock (this.lockObject)
{
// Manipulate the state.
}
}
}
You can also use declarative synchronization, but this has an obvious drawback that you have to get from ContextBoundObject
and all methods decorated with the attribute Synchronization
use the same lock object limiting the granularity of the lock.
internal class Foo : ContextBoundObject
{
[Synchronization]
private void ChangeVars()
{
// Manipulate the state.
}
}
source to share