I generally run 3 sets of tests:
- one thread to check correct behaviour in single threaded environment
- number of processors + 1 (or whatever the typical application setting is)
- many threads (say 1000) to increase context switching and contention
And for the multi threaded tests, I try to maximize interleaving, typically by synchronizing the beginning of the tasks with a CountDownLatch, so that all threads start their tasks more or less at the same time.
I also try to avoid additional synchronization during the tests (for example by using a thread safe structure to store some results) as it might "re-sycnchronize" the tested code artificially - to be assessed on a case by case basis.
JCiP, chapter 12, is a good source of inspiration for efficient multithreading testing (i.e. gives many hints to provoke concurrency bugs).
And finally, as noted by @PeterLawrey, you can't guarantee that your code is thread safe with testing, you can only try to increase your chance of finding concurrency bugs.