views:

2820

answers:

12

Does it mean that two threads can't change the undelying data simultaneously? or does it mean that the given code component will run with unpredictable results when more than one thread are running it?

+23  A: 

from wikipedia :

Thread safety is a computer programming concept applicable in the context of multi-threaded programs. A piece of code is thread-safe if it functions correctly during simultaneous execution by multiple threads. In particular, it must satisfy the need for multiple threads to access the same shared data, and the need for a shared piece of data to be accessed by only one thread at any given time.

...

There are a few ways to achieve thread safety:

Re-entrancy

Writing code in such a way that it can be partially executed by one task, reentered by another task, and then resumed from the original task. This requires the saving of state information in variables local to each task, usually on its stack, instead of in static or global variables.

Mutual exclusion

Access to shared data is serialized using mechanisms that ensure only one thread reads or writes the shared data at any time. Great care is required if a piece of code accesses multiple shared pieces of data—problems include race conditions, deadlocks, livelocks, starvation, and various other ills enumerated in many operating systems textbooks.

Thread-local storage

Variables are localized so that each thread has its own private copy. These variables retain their values across subroutine and other code boundaries, and are thread-safe since they are local to each thread, even though the code which accesses them might be reentrant.

Atomic operations

Shared data are accessed by using atomic operations which cannot be interrupted by other threads. This usually requires using special machine language instructions, which might be available in a runtime library. Since the operations are atomic, the shared data are always kept in a valid state, no matter what other threads access it. Atomic operations form the basis of many thread locking mechanisms.

read more :

http://en.wikipedia.org/wiki/Thread_safety


Blauohr
Descriptive answer. Most of the other answers are also correct. Thanks everyone
Varun Mahajan
you could have used wikipedia...
gatoatigrado
+9  A: 

Thread-safe code is code that will work even if many Threads are executing it simultaneously.

http://mindprod.com/jgloss/threadsafe.html

Marek Blotny
Within the same process!
Ali A
Indeed, in the same process :)
Marek Blotny
"To write code that will run stably for weeks takes extreme paranoia." That's a quote that I like :)
Jim T
+7  A: 

Thread-safe-code works as specified, even when entered simultaneously by different threads. This often means, that internal data-structures or operations that should run uninterrupted are protected against different modifications at the same time.

Mnementh
+4  A: 

As others have pointed out, thread safety means that a piece of code will work without errors if it's used by more than one thread at once.

It's worth being aware that this sometimes comes at a cost, of computer time and more complex coding, so it isn't always desirable. If a class can be safely used on only one thread, it may be better to do so.

For example, Java has two classes that are almost equivalent, StringBuffer and StringBuilder. The difference is that StringBuffer is thread-safe, so a single instance of a StringBuffer may be used by multiple threads at once. StringBuilder is not thread-safe, and is designed as a higher-performance replacement for those cases (the vast majority) when the String is built by only on thread.

Marcus Downing
+2  A: 

Don't confuse thread safety with determinism. Thread-safe code can also be non-deterministic. Given the difficulty of debugging problems with threaded code, this is probably the normal case. :-)

Thread safety simply ensures that when a thread is modifying or reading shared data, no other thread can access it in a way that changes the data. If your code depends on a certain order for execution for correctness, then you need other synchronization mechanisms beyond those required for thread safety to ensure this.

tvanfosson
A: 

Simply - code will run find if many threads are executing this code at the same time.

Greg Balajewicz
A: 

Yes and yes. It implies that data is not modified by more than one thread simultaneously. However, your program might work as expected, and appear thread-safe, even if it is fundamentally not.

Note that the unpredictablility of results is a consequence of 'race-conditions' that probably result in data being modified in an order other than the expected one.

Steve Knight
+2  A: 

To complete other answers:

Synchronization is only a worry when the code in your method does one of two things:

  1. works with some outside resource that isn't thread safe.
  2. Reads or changes a persistent object or class field

This means that variables defined WITHIN your method are always threadsafe. Every call to a method has its own version of these variables. If the method is called by another thread, or by the same thread, or even if the method calls itself (recursion), the values of these variables are not shared.

Thread scheduling is not guaranteed to be round-robin. A task may totally hog the CPU at the expense of threads of the same priority. You can use Thread.yield() to have a conscience. You can use (in java) Thread.setPriority(Thread.NORM_PRIORITY-1) to lower a thread's priority

Plus beware of:

  • the large runtime cost (already mentionned by others) on applications that iterate over these "thread-safe" structures.
  • Thread.sleep(5000) is supposed to sleep for 5 seconds. However, if somebody changes the system time, you may sleep for a very long time or no time at all. The OS records the wake up time in absolute form, not relative.
VonC
+1  A: 

Yes and no.

Thread safety is a little bit more than just making sure your shared data is accessed by only one thread at a time. You have to ensure sequential access to shared data, while at the same time avoiding race conditions, deadlocks, livelocks, and resource starvation.

Unpredictable results when multiple threads are running is not a required condition of thread-safe code, but it is often a by-product. For example, you could have a producer-consumer scheme set up with a shared queue, one producer thread, and few consumer threads, and the data flow might be perfectly predictable. If you start to introduce more consumers you'll see more random looking results.

Bill the Lizard
+2  A: 

An easier way to understand it, is what make code not thread-safe. There's two main issue that will make a threaded application to have unwanted behavior.

  • Accessing shared variable without locking
    This variable could be modify by another thread while executing the function. You want to prevent it with a locking mechanism to be sure of the behavior of your function. General rule is to keep the lock for the shortest time possible.

  • Deadlock cause by mutual dependency on shared variable
    If you have two shared variable A and B. In one function, you lock A first than later you lock B. In another function, you start locking B and after a while, you lock A. This is a potential deadlock where first function will wait for B to be unlocked when second function will wait for A to be unlocked. This issue will probably not occurs in your development environment and only from time to time. To avoid it, all lock must be always in the same order.

Hapkido
+4  A: 

I like the definition from Brian Goetz's Java Concurrency in Practice for its comprehensiveness

"A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code."

Buu Nguyen
+5  A: 

A more informative question is what makes code not thread safe- and the answer is that there are four conditions that must be true... Imagine the following code (and it's machine language translation)

totalRequests = totalRequests + 1
MOV EAX, [totalRequests]   // load memory for  totalRequests
                           // into register
INC EAX                    // update register
MOV [totalRequests], EAX   // store updated value back to memory
  1. The first condition is that there are memory locations that are accessible from more than one thread. Typically, these locations are global/static variables or are heap memory reachable from global/static variables. Each thread gets it's own stack frame for function/method scoped local variables, so these local function/method variables, otoh, (which are on the stack) are accessible only from the one thread that owns that stack.
  2. The second condition is that there is a property (often called an invariant), which is associated with these shared memory locations that must be true, or valid, for the program to function correctly. In the above example, the property is that “totalRequests must accurately represent the total number of times any thread has executed any part of the increment statement”. Typically, the property needs to hold true (in this case, totalRequests must hold an accurate count) before an update occurs for the update to be correct.
  3. The third condition is that the invariant property does NOT hold during some part of the actual update. (It is transiently invalid or false during some portion of the processing). In this particular case, from the time totalRequests is fetched until the time it is stored, totalRequests does not satisfy the invariant.
  4. The fourth and final condition that must occur for a race to happen (and for the code to therefore NOT be "thread-safe") is that another thread must be able to access the shared memory while the invariant is broken, thereby causing inconsistent or incorrect behavior.
Charles Bretana