3

For example we have 5 running threads. Each of them call the same method. When the methods is called, it will run on the current thread? That means that the same method will run separately on the different threads in the (relatively) same time?

Example:

public string GetHhmlCode(string url) { // ... Some code here return html; } 

If we call this method from different threads with different parameter in the same time, the result will be return to appropriate thread which means that the code runs separately on different threads?

2

2 Answers 2

8

The short answer is to the first question is: Yes! The method will be executed by multiple threads concurrently.

The answer to the second question is: Yes (with reservations)! If you enter from a given thread context, then the method will return to the same thread context and all the treads will generally behave as if the other thread doesn't exist. However, this will quickly change if the threads have to read and/or write on the same variable. Consider this situation:

class HttpClient { private volatile bool _httpClientConnected; //.. initialize in constructor public string GetHtmlCode(string url) { string html = string.Empty; if(_httpClientConnected) { html = FetchPage(url); } return html; } public void Connect() { _httpClientConnected = true; ConnectClient(); } public void Disconnect() { _httpClientConnected = false; DisconnectClient(); } } 

Suppose it is required that the client is connected for a page to be successfully fetched, then consider this order of execution:

Thread 1: calls GetHtmlCode Thread 1: initialize local html variable Thread 3: calls Disconnect() Therad 2: calls GetHtmlCode Thread 2: initialize local html variable Thread 1: evaluate _httpClientConnected flag Thread 3: sets _httpClientConnected to false Therad 3: calls DisconnectClient() and successfully disconnects THread 3: exits the Disconnect() method. Thread 1: calls FetchPage() Therad 2: evaluates _httpClientConnected flag Thread 2: returns empty html string Therad 1: catches an exception because it attempted to fetch a page when the client was disconnected 

Thread 2 exited correctly, but Thread 1 possibly threw an exception and it may cause other problems in your code. Note that read/writing to the flag itself will be safe (i.e. those operations are atomic and visible to all threads due to the flag being labeled as volatile), however there is a race condition because the flag can be set AFTER a thread has already evaluated it. In this case there are a couple of ways to guard against the problem:

  1. Use a synchronization block (something like lock(syncObject){...})
  2. Create a separate http client for each thread (probably more efficient and it avoids synchronization).

Now let's look at another example:

public string GetHtmlCode(string url) { string html = string.Empty; string schema = GetSchema(url); if(schema.Equals("http://")) { // get the html code } return html; } 

Suppose the following happens:

Thread 1: calls GetHtmlCode("http://www.abc.com/"); Thread 1: html is assigned an empty string Thread 2: calls GetHtmlCode("ftp://www.xyz.com/"); Thread 2: html is assigned an empty string Therad 1: assigns it's schema to the schema variable Thread 2: assigns it's schema to the schema varaible Thread 2: evaluates schema.Equals("http://") Thread 1: evaluates schema.Equals("http://") Thread 1: fetches html code Therad 2: returns html Therad 1: returns html 

In this case both threads entered the method with different parameters and only Thread 1 entered with a parameter that could allow it to fetch a page, but Thread 2 did not interfere with Thread 1. The reason why this happens is because the threads don't share any common variables. A separate instance of the url parameter is passed in and each thread also gets its own local instance of schema (i.e. the schema is not shared because it only exists in the context of the calling thread).

Sign up to request clarification or add additional context in comments.

2 Comments

Yes - I would certainly go with a separate http client for each thread.
if you introduce a race condition, and have to implement a lock() mechanism, i always wondered if that meant that all threads would have to wait until the other one is done to proceed? If so, doesn't that kind of defeat the purpose of concurrent threading if you have to wait? I always find it easier, especially if i have to pass params to the method, to simply copy/paste the execute code into my thread's DoWork() method. That way they all truly run concurrently and efficiency is achieved. Yes?
2

mark this method as static and don't refer external variables inside this method. then it will work fine.

1 Comment

While these might be good ideas in general, neither is necessary nor sufficient for thread safety.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.