Here are couple of best practices which I follow while writing concurrent code in Java:
a) Always name your thread, this will help in debugging.
b) minimize the scope of synchronization, instead of making whole method synchronized, only critical section should be synchronized.
c) prefer volatile over synchronized if you can can.
e) use higher level concurrency utilities instead of waitn() and notify for inter thread communication e.g. BlockingQueue, CountDownLatch and Semeaphore.
e) Prefer concurrent collection over synchronized collection in Java. They provide better scalability.