C# version of java's synchronized keyword?
First - most classes will never need to be thread-safe. Use YAGNI: only apply thread-safety when you know you actually are going to use it (and test it).
For the method-level stuff, there is [MethodImpl]
:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
This can also be used on accessors (properties and events):
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
Note that field-like events are synchronized by default, while auto-implemented properties are not:
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
Personally, I don't like the implementation of MethodImpl
as it locks this
or typeof(Foo)
- which is against best practice. The preferred option is to use your own locks:
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
Note that for field-like events, the locking implementation is dependent on the compiler; in older Microsoft compilers it is a lock(this)
/ lock(Type)
- however, in more recent compilers it uses Interlocked
updates - so thread-safe without the nasty parts.
This allows more granular usage, and allows use of Monitor.Wait
/Monitor.Pulse
etc to communicate between threads.
A related blog entry (later revisited).
Synchronized methods in C#
Try this:
using System.Runtime.CompilerServices;
using System.Threading;
public class MessageBuffer
{
// Shared resources up here
public MessageBuffer()
{
// Initiating the shared resources
}
[MethodImpl(MethodImplOptions.Synchronized)]
public virtual void post(object obj)
{
// Do stuff
Monitor.Wait(this);
// Do more stuff
Monitor.PulseAll(this);
// Do even more stuff
}
[MethodImpl(MethodImplOptions.Synchronized)]
public virtual object fetch()
{
// Do stuff
Monitor.Wait(this);
// Do more stuff
Monitor.PulseAll(this);
// Do even more stuff and return the object
}
}
Couple of questions regarding the synchronized keyword in Java (and C#'s lock)
1 Are the following classes equivalent in Java? if no, why?
They differ by what instance they synchronize on and thus are affected by the differences between those instances.
Class Abc
uses the Abc
instance that the method is being invoked upon. Other code with access to the instance can use it to synchronize as well by explicitly using the instance in a synchronized block.
The synchronize code blocks in Class Def
explicitly name the instance they synchronizes with. Since this instance is private to the Def
instance, code external to Def
cannot use it to synchronize (unless the instance is somehow leaked).
Some may argue that the Def
approach is much safer, that it is important to encapsulate your locks for the same reason you should use private instance variables.
Finally, there are the differences between the synchronized keyword and using the synchronized statement, e.g. the synchronized statement can lock on any object, not just the instance of the executing code, the synchronize keyword is slightly more efficient, etc.
2a Also, what would be the problem of in Def, using this as synchronized parameter instead of lock?
No problem. Using synchronized keyword on an instance method is semantically identical to wrapping the code of the method in a synchronized block synchronized on this
(the synchronized keyword is slightly more efficient). Using the synchronized keyword on a static method is the same as using a synchronized block synchronized on the class itself (e.g. synchronized(FooBar.class) { ... }
).
2b Is the following the problem?
No, locks in Java are reentrant, which just means that the thread holding the lock on the protecting instance can enter and exit any other code block synchronized on the same instance.
3a Are synchronized statements in Java just like C#'s lock statements? If no, what are their differences?
Semantically equivalent.
http://en.csharp-online.net/CSharp_FAQ:_What_is_the_difference_between_CSharp_lock_and_Java_synchronized#Synchronized_code_blocks
But note this answer about Monitor.Enter
and Monitor.Exit
Are there any differences between Java's "synchronized" and C#'s "lock"?
3b If yes, why doesn't C# also allow to lock the methods, like Java allows?
It does - use the [MethodImpl(MethodImplOptions.Synchronized)]
annotation.
http://en.csharp-online.net/CSharp_FAQ:_What_is_the_difference_between_CSharp_lock_and_Java_synchronized#Synchronized_methods
4 Thread1 calls xyz.add(0) and at the same time Thread2 tries to call xyz.show666(). Thread2 has to wait for Thread1 to finish with xyz.add(0) althtough it doesn't need any info directly related with the lock. Is that it?
No, a lot of people assume "locking" an instance affects the entire instance. It only affects synchronized code (synchronized methods and code within a synchronized statement) that is synchronized on that instance. Unsynchronized code is unaffected (at least until it hits a synchronized statement or calls a synchronized method).
The unsynchronized method show666()
won't cause the thread to block. Nothing changes if the synchronized(this)
statements were changed into synchronized
methods - again show666
won't block (unless its synchronized too).
Are there any differences between Java's synchronized and C#'s lock?
According to this site: http://en.csharp-online.net/CSharp_FAQ:_What_is_the_difference_between_CSharp_lock_and_Java_synchronized, C# lock
and Java synchronized
code blocks are "semantically identical", while for methods, Java uses synchronized
while C# uses an attribute: [MethodImpl(MethodImplOptions.Synchronized)]
.
What is the equivelent of the synchronize block in Java, in C# ASP.NET?
You could use the lock statement or decorate a method with the [MethodImpl(MethodImplOptions.Synchronized)]
attribute to allow access to this block/method only from a single thread at a time.
Java-like thread synchronization in C#
Something like this mayhaps:
using System.Runtime.CompilerServices;
...
private int a;
private int b;
private int c;
[MethodImpl(MethodImplOptions.Synchronized)]
private void changeVars()
{
a = 4;
b = 2;
c = a+b;
}
Related Topics
Firefox Browser Does Not Reload the Update CSS/Js Files
Asp.Net-Mvc: Razor '@' Symbol in Js File
Does Java Have Something Similar to C# Properties
How to Indefinitely Pause a Thread
How to Use the Iequalitycomparer
Biginteger to Hex/Decimal/Octal/Binary Strings
How to Find Multiple Occurrences with Regex Groups
Console.Read Not Returning My Int32
How to Make the Return Type of a Method Generic
Visual Studio: Contextswitchdeadlock
How to Convert an Object to a Byte Array in C#
How Does Wcf Deserialization Instantiate Objects Without Calling a Constructor
Getting HTML Body Content in Winforms Webbrowser After Body Onload Event Executes
Send Push to Android by C# Using Fcm (Firebase Cloud Messaging)
Using C# Reflection to Call a Constructor