Stereotypes result in a logical classification of classes in your system - they create sort of buckets.. By tagging a class as a particular sterotype, you are documenting a common behavior, responsibilities and restrictions on all classes belonging to that stereotype. For instance, by tagging a class as a <<SingleThreadModel>>, you are saying
everything that is true for a SingleThreadModel are true for this class too.
Constraints on the otherhand, can be very specific to a particular object state or variation of a class. It is a sort of a global rule on all objects of that class, sometimes referred to as "covariants". They can be used with or without stereotypes, but when used in conjunction with stereotypes, they act as subqualifiers ie., add more qualifications. For instance, a class can have a stereotype of <<DependentObject>> and can have a constraint that says AccountBalance > 1550. As you can see, constraints almost always are applied on attributes, and hence has an implicit reference to the object state.
It is a good idea to use stereotypes, but be careful when using constraints and avoid them if possible.
You should not use constraints unless they are applicable to all instances ie., you should be able to pick an instance of the class at random and should be able to evaluate the constraint. From a cosmetic point of view, they tend to clutter the class diagram, espcially when the model evolves during the course of time and you end up adding more and more constraints....