(concise?) definition of thread safety Wikipedia has the following definition:


  Thread safety is a computer programming concept applicable in the
  context of multi-threaded programs. A piece of code is thread-safe if
  it only manipulates shared data structures in a manner that guarantees
  safe execution by multiple threads at the same time. There are various strategies for making thread-safe data structures.[1][2] ... and so on ( http://en.wikipedia.org/wiki/Thread-safety )


So, code is thread-safe if it operates in thread-safe manner! Hmm...

However, precise definition seems not to be simple. A naive approach is:

Thread-safety means that program's observable behavior does not depend on eligible thread scheduling order.

Still, it may be incorrect definition. Say, threads may log  messages into log file, and reodering of log messages may be OK. So program observable behavior may vary, but the program may be considered thread-safe.  

Probably, we need to specify allowed types of different program observable behaviors while being thread-safe.

Yet another complication: there may be  thread-safe (or thread-unsafe) code, not the whole program. (One may think about compositional properties of (non-)thread-safe code and so on)

So, the questions are: how to precisely define thread safety? Is there concise definition? What work was done to define thread safety?

UPDATE: Thanks for all the high quality links you supplied. The links contain answers to additional question(s) that I planned to ask. Feel free to add new (appropriate) links even though I have chosen my prefered answer.
There has been a lot of work on this, usually under the heading of "memory models".  See, for example:


The Java memory model
Foundations of the C++ Concurrency Memory Model by Boehm and Adve
Lots of recent work by Peter Sewell's group on C++ concurrency and hardware memory models