Short answer... Threads in Java have been used in "real programming" -- realtime applications, commercial products, software libraries, application servers, etc. -- for more than 10 years, so it is safe to assume it works...
Longer answer... Threads have always been somewhat non-deterministic. This is also true for Solaris threads, Windows threads, POSIX, etc. To manage this, developers generally...
1. Use synchronization techniques such as mutexes, semaphores, condition variables, reader-writer locks, message pipes, etc., to manage the flow of threads or the data they manage.
2. Understand the non-deterministic nature, and design applications to work under those conditions. (transactional techniques, optimistic locking techniques)
Unfortunately the learning curve can be somewhat steep. It can take years of experience before one can understand all the edge conditions for case one. And many programmers never even get to case two.
Henry