Here is a great post about the difference between atomic and nonatomic:
Assuming that you are @synthesizing the method implementations, atomic
  vs. non-atomic changes the generated code. If you are writing your own
  setter/getters, atomic/nonatomic/retain/assign/copy are merely
  advisory.
With atomic, the synthesized setter/getter will ensure that a whole
  value is always returned from the getter or set by the setter,
  regardless of setter activity on any other thread. That is, if thread
  A is in the middle of the getter while thread B calls the setter, an
  actual viable value -- an autoreleased object, most likely -- will be
  returned to the caller in A.
In nonatomic, no such guarantees are made. Thus, nonatomic is
  considerably faster than atomic.
What atomic does not do is make any guarantees about thread safety. If
  thread A is calling the getter simultaneously with thread B and C
  calling the setter with different values, thread A may get any one of
  the three values returned -- the one prior to any setters being called
  or either of the values passed into the setters in B and C. Likewise,
  the object may end up with the value from B or C, no way to tell.
Ensuring data integrity -- one of the primary challenges of
  multi-threaded programming -- is achieved by other means.
Note that the default is atomic, so the last example is equivalent to
@property (atomic) int myInt
Another default value is assign, therefore these two options are equivalent:
@property (nonatomic, assign) int myInt
@property (nonatomic) int myInt
And, similarly, the following are also equivalent
@property (atomic, assign) int myInt
@property (atomic) int myInt
EDIT: As Josh points out, atomic being included is a hypothetical example.