Ashod Nakashian is well into his second decade leading and developing professional software solutions. Throughout the years, Ashod has participated in projects covering a wide gamut of the software spectrum from web-based services, state-of-the-art audio/video processing and conversion solutions, multi-tier data and email migration and archival solutions to mission-critical real-time electronic trading servers. When not designing, coding or debugging, he enjoys reading, writing and photography. Ashod is a DZone MVB and is not an employee of DZone and has posted 18 posts at DZone. You can read more from them at their website. View Full User Profile

(Almost) Everything You Read About Threading Is Wrong!

07.10.2011
| 5256 views |
  • submit to reddit

Threading is on the front pages more than ever, so to speak. Where only a few years ago programmers could brush the topic aside as complicated and not-very-useful, it’s increasingly harder to hide behind those excuses. Multi-core systems are the status quo and the only real way to get better performance (read: scale) is to have multi-threaded code.

So it’s no surprise that the topic is revived and there is more talk about it. And what threading if one doesn’t mention the pitfalls and problems? Consider the following question:

int x = 1;
int y = 0;

if (y == 0)
{
   // Can x be anything but 1 at this point?
}

There is no shortage of this type of questions. And there is no shortage of answers either!

The only correct answer to the above question is: It depends on the language!

What does the keyword volatile do? Same answer.

Does my code suffer from the ABA problem? Same answer (but that one is more complicated)

Similar question, same answer.

// Thread 1
x = 1;
y = 0;

// Thread 2
int a = x;
int b = y; // if b == 0, is a == 1?

Here is a pdf presentation of a lock-free hashtable in Java. Here is the video presentation. Again, if the same algorithm implemented in a different language, the result will be different. Namely, it won’t work.

Why? Because the memory models are different. C++ has a very, very different memory model than .Net than Java. (It wouldn’t be entirely wrong to say that C/C++ don’t define any memory coherency models as such.) Each in their turn probably have a different memory model from other languages. And talking about threading without knowing the memory model is like assuming you can drive at the same speed on all roads. Well, some aren’t even paved, yet some have minimum speed.

It’s very unfortunate that an already complex subject is made even more confusing by the differences in languages and their guarantees, or lack thereof. There is no shortage of confused, misleading and downright incorrect information when it comes to threading. Consider that locks don’t even protect your code against out-of-order execution. But in which language is that?

This is made even more complicated by the fact that processors and hardware architectures come with their own set of guarantees and reservations. So reading on those without taking into account what the language in question abstracts from the hardware, is yet another way to throw oneself in the rabbit hole.

So, the next time you read (or write) about threading issues, make sure you know which language is in question. If it doesn’t say, stop reading. Without that small one-word detail, everything you learn is wrong, regardless of how detailed and coherent it is. Because precise doesn’t necessarily mean accurate.

From http://blog.ashodnakashian.com/2011/07/almost-everything-you-read-about-threading-is-wrong/

Published at DZone with permission of Ashod Nakashian, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Ronald Miura replied on Mon, 2011/07/11 - 1:39pm

Well, most articles about concurrency I've ever read are language-specific. Many were probably wrong for some reason (the author didn't understand the memory model, or even concurrency in general), but not because they didn't mention the target language/platform/architecture.

Cosmin Mutu replied on Tue, 2011/07/12 - 7:34am

I thought I`ll be reading something interesting when I opened your article, but ... well ... shame on me for beeing fooled by the title.

Of course threading is dependent on the language. That`s why we have multi-processor parallelism and multi-threaded parallelism... one is using processes as the lowest unit of work (OS is the owner) the later one is using "thread" as the lowest unit of work (JVM is the owner in the case of JAVA).

Anyway, you should pick your titles better.

 

Ashod Nakashian replied on Tue, 2011/07/12 - 9:08am in response to: Cosmin Mutu

> Anyway, you should pick your titles better.

That's not as easy as it may seem. But back to your point, while it's obvious that "threading is dependent on the language" many developers working with multiple languages don't actually realize that what is thread-safe in one language is completely broken in another. The point isn't the dependency, rather that theory can't be applied blindly. A lock doesn't give the same guarantees equally in all languages. If you've worked with Java only, then you're lucky. Java has a pretty good memory model.

Cosmin Mutu replied on Thu, 2011/07/14 - 2:49am in response to: Ashod Nakashian

I agree with you. I also think that anyone who is using THREADS (or any form of parallelism) should first document himself a bit (if possible 2 bits).

"A lock doesn't give the same guarantees equally in all languages" ... this sounds interesting.

So you`re saying that the concept of lock, implemented correctly in two different languages is not doing what it should do? (Of course there are small differences, but I am talking about the main functionality, locking an object).

Well, if this is the case, then that language does not support "locking" or it has a poor support for synchronized units of work.

Also I would be very interested to learn about such a difference between two languages which are rather simmilar than different (for example, C, C#, Java, PHP).

Yup, I`ve only used JAVA for threading so far.

 

 

 

 

Ashod Nakashian replied on Fri, 2011/07/15 - 6:53am in response to: Cosmin Mutu

"So you`re saying that the concept of lock, implemented correctly in two different languages is not doing what it should do?"

No. I'm saying they don't necessarily make the same guarantees.

For example, in some language a lock may guarantee a full memory-barrier, which ensures no reordering can take place. In addition, it may guarantee that all writes are flushed from CPU cache to main memory (which is shared between CPUs.) These aren't guarantees that all locks must make. As you can tell, the purpose of the lock is to ensure exclusive execution of a single thread at a time. The side-effects that I mentioned may be very welcome and useful, but they aren't necessarily part of the lock definition. So one shouldn't make assumptions across languages. Because while all locks should behave similarly, there are other nuances.

As a concrete example, consider that using locks isn't enough to have a thread-safe singleton. This pattern has been discussed ad nauseam. Here is in C++, in Java and in C#. The problem isn't in the lock, usage of locking or implementation. The problem is in memory models, compiler reordering and out-of-order execution.

To be fair, for most all this is academic talk that they wouldn't lose sleep over. And perhaps we shouldn't either. However the issues are real and do affect the stability and/or correctness of some applications, and therefore are of great importance to some.

Cosmin Mutu replied on Mon, 2011/07/25 - 7:40am in response to: Ashod Nakashian

Ok, your reasoning is fair enough,

I declare myself happy :)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.