.NET Framework - Thread contention and static methods

Asked By C. on 13-Jul-11 07:16 AM
Hello,

I have always made CRUD methods on my Business Objects static.
However, after going through the MS cert training kit 70-515, I came
across this:

Visual Basic), the ObjectDataSource can use these
methods without creating an instance of the actual business object. In
this case, however, keep
in mind that you could end up with performance issues related to
thread contention as multiple
requests try to access the same static method."

This passage would seem to suggest that each thread can only enter a
static method one at a time. If so, would not this cause scalability
issues if a static method is used frequently in an application?

I had never heard this, any explanation would be appeciated!

Chris




Peter Duniho replied to C. on 13-Jul-11 10:17 AM
What's the context?

In a plain C# program, there is no such problem.  A given static method
can be executed simultaneously by as many threads as could call it.

But the text you quote may be referring to a specific scenario in which
some framework in use is imposing some kind of synchronization on your
behalf.  Or it may be making the assumption that your own implementation
requires some kind of synchronization in each static method.  Or it may
simply be warning against the _possibility_ that you require your own
synchronization for some reason.

Unless you are using the same books that Tony Johansson insists on using
(I do not know which books those are, but based on past posts from him
here they are reliably confusing at best and misleading and wrong at
worst), I would say there is a pretty good chance the text is accurate as
far as it goes, given whatever specific context it is discussing.  But
you cannot generalize to C# programs overall.  Absent additional work,
static methods do not inherently come with synchronization.

Pete
Registered User replied to C. on 13-Jul-11 10:28 AM
Multiple threads can operate within a static method at the
simultaneously. There is no thread safety; changes to static members
by one thread are visible to other threads.

Copy the example below into a console app and play with the value of
sleepFor. The value of name and Thread.CurrentThread.Name may or may
not be the same inside the if statement. There is also a possibility
both threads will enter the if statement; the second thread might use
the original value of done before the first thread changes that value
to true.

static void Main(string[] args)
{
Thread.CurrentThread.Name = "main";
Thread worker = new Thread(Go);
worker.Name = "worker";
worker.Start();
Go();

Console.ReadKey();
}

static bool done;
static string name;
static int sleepFor = 10000;
static void Go()
{
name = Thread.CurrentThread.Name;
Console.WriteLine("Sleep : {0} : {1}", name,
Thread.CurrentThread.Name);
Thread.Sleep(sleepFor);
if (!done)
{
done = true;
Console.WriteLine("Done : {0} : {1}", name,
Thread.CurrentThread.Name);
}
}

To make the method thread-safe a lock can be used. The results are
more predictable because only one thread at a time is in the body of
the static method.

static readonly object obj = new object();
static void Go()
{
lock (obj)
{
name = Thread.CurrentThread.Name;
Console.WriteLine("Sleep : {0} : {1}", name,
Thread.CurrentThread.Name);
Thread.Sleep(10000);
if (!done)
{
Console.WriteLine("Done : {0} : {1}", name,
Thread.CurrentThread.Name);
done = true;
}
}
}


Probably not the best explanation but it does fall under the 'any'
flag...

regards
A.G.
Arne_Vajhøj replied to C. on 13-Jul-11 09:58 PM
Not good.

Too tightly coupled. An interface is good - a class with virtual methods
that can be overriden can do.


Multiple threads can certainly call the same static methods at
the same time.

I will guess that the real story is:
- multiple threads calling the same static methods works perfect
if the method only uses local variable
- if it uses static fields and it does not synchronize then it is
not thread safe
- if it uses static fields and it does synchronize then it is
performance can suffer
- by using non static fields and methods each thread can get its
own instance to use which will be both thread safe and perform

Arne
Peter Duniho replied to Registered User on 14-Jul-11 01:05 AM
Correction: "changes to static members by one thread _might_ be visible
to other threads".  One needs to use some synchronization mechanism to
guarantee that they are visible to other threads.  And of course if one
has implemented some synchronization mechanism, then at least by design
the method is thread-safe.

My understanding is that on x86/x64 hardware, Intel's memory model
results in volatile or near-volatile semantics for all memory access, so
the main reason one would see thread safety issues absent
synchronization on those CPUs is because of optimizations, not due to
memory coherency issues.  But even those can be an issue, and of course
on other hardware the memory coherency issues are more significant.

In situations where optimizations and/or memory coherency issues come
up, in your code example it is even possible for each thread to
essentially have its own copy of each static field, so that the output
from each thread is entirely consistent within the thread, but the
output is interleaved and independent between threads.

All that said, the bottom line here is the same what you essentially
describe and as I wrote before: for a _plain_ C# program, without any
explicit synchronization, static methods are not synchronized.  In other
contexts, this may or may not continue to hold to be true.

Pete
Registered User replied to Peter Duniho on 14-Jul-11 09:04 AM
In this context the words 'can' and 'might' carry equivalent meanings.
Neither one bears the explicit promise of 'will'.

- good stuff snipped -

The sample demonstrates the OP's inference is incorrect.

- quote -

This passage would seem to suggest that each thread can only enter a
static method one at a time.

- end quote -

I did not see a reason for further detail. Besides if further detail is
necessary, there are people like you who can explain things much
better than I.

regards
A.G.
Peter Duniho replied to Registered User on 14-Jul-11 10:03 AM
A true statement, but not relevant to what I wrote.

In the quoted text, the word "can" is applied in the context of
simultaneously [sic]".  Yes, more than one thread can execute the code
at a time, and in that statement you could equivalently use the word

But it does not follow from that that "changes to static members by one
thread _are_ visible to other threads" (emphasis mine).  In fact, that is
the whole point of my reply.

I did not replace the word "can" with "might".  I put the "might" in a
completely different place, and with good reason.  Even if multiple
threads wind up executing the same code simultaneously, that is no
guarantee that changes made by each thread is visible to other threads.


In a specific context.  We do not know enough about the context described
by the text the OP is asking about to know whether that specific context
matches.

There is nothing wrong with the example you posted per se.  I just think
it is important for the OP to keep in mind that it may or may not be
applicable to the text he is asking about.  We have incomplete
information regarding that.

Pete
Arne_Vajhøj replied to Registered User on 16-Jul-11 08:19 PM
I think the point of two threads running in the same static
method can be illustrated simpler:

using System;
using System.Threading;

namespace E
{
public class Program
{
public static void Main(string[] args)
{
(new Thread(Go)).Start();
(new Thread(Go)).Start();
Console.ReadKey();
}
public static void Go()
{
Console.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId +
Thread.Sleep(1000);
Console.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId +
}
}
}

Arne
Arne_Vajhøj replied to Registered User on 16-Jul-11 08:19 PM
True.

But the word "are" carry a meaning that is equivalent of "will".

Arne