To avoid dead lock:
[ul]
[li]Always aquire in same order, if you require more than one resource.
[ul]
[li]Get A then B if need A and B any time durring code[/li]
[li]Get just A if need just A.[/li]
[li]If you have B, and need A, let go of B (if it is safe to do so to maintian mutal exclussion)[/li]
[li]You can have either A or B alone at anytime, as long as you don't need to grab the other.[/li]
[/ul][/li]
[li]Release in oppiste order than aquire (Java forces you to this -- if your just using sychronize).[/li]
[li]Increase in number of lock = increase probability of accidental dead lock. Decrease in the number of locks means more things locking on one item and slower speed. Here you have the age old trade off between useability and security.[/li]
[li]Every shared mutable state requires protection, any protection aquired needs to be released in a timely fashion ; but only after the whole operation with the mutable state is completed.[/li]
[/ul]
Sychronization is the easiest thing and the hardest thing to do in computers. To make sure that no more than one process/thread is changing something, don't let anyone touch it. To make sure that everyone has access to something always don't protect it. The Zen in programming is finding the middle ground between the two that does something useful. Use these tips well grasshopper.