From codeproject.com(http://www.codeproject.com/csharp/syncroot.asp)
Thread aware:
At any given time, at most one thread can be active on the object. The object is aware of the threads around it and protects itself from the threads by putting all the threads in a queue. Since there can be only a single thread active on the object at any given time, the object will always preserve its state. There will not be any synchronization problems.
Thread safe:
At a given time, multiple threads can be active on the object. The object knows how to deal with them. It has properly synchronized access to its shared resources. It can preserve its state data in this multi-threaded environment (i.e. it will not fall into intermediate and/or indeterminate states). It is safe to use this object in a multi-threaded environment.
Using an object that is neither thread-aware nor thread-safe may result in getting incorrect and random data and mysterious exceptions (due to trying to access the object when it is being used by a thread and is in an unstable, in-between state at the instant of access of the second thread).