From: http://www.wilsonmar.com/1threads.htm
| If you don't when you should: | If you do when you shouldn't: |
| "The consequences of failing to properly synchronize are severe: data corruption and race conditions, which can cause programs to crash, produce incorrect results, or behave unpredictably. Even worse, these conditions are likely to occur only rarely and sporadically (making the problem hard to detect and reproduce)." | "On the other hand, using synchronization inappropriately or excessively can lead to other problems, such as poor performance and deadlock." |
"A race condition is a situation in which two or more threads or processes are reading or writing some shared data, and the final result depends on the timing of how the threads are scheduled. Race conditions can lead to unpredictable results and subtle program bugs."
"To make your programs thread-safe, you must first identify what data will be shared across threads. If you are writing data that may be read later by another thread, or reading data that may have been written by another thread, then that data is shared, and you must synchronize when accessing it. ... these rules also apply in situations where you are simply checking if a shared reference is non-null."
"In simple cases, you can protect data fields by simply declaring them volatile; in other cases, you must acquire a lock before reading or writing the shared data, and it is a good practice to explicitly identify what lock is being used to protect a given field or object, and document that with your code."
"The Collections classes ... are unsynchronized, but for each interface defined in the framework, there is a synchronized wrapper (for example, Collections.synchronizedMap()) that wraps each method with a synchronized version."
from: http://www.cs.wcupa.edu/~rkline/OS/Java_locks_semaphores.html (link no longer valid)

Image from: http://www.wilsonmar.com/1threads.htm
Threads should yield periodically to make sure other threads of the same priority have a chance to run:
Thread.yield();
Thread.sleep(milliseconds);
"Thread settings give hints to the thread scheduler, but do not guarantee a specific behavior... A Java thread's priority is specified with an integer from (the lowest) 1 to 10 (the highest), constants Thread.MIN_PRIORITY and Thread.MAX_PRIORITY. By default, the setPriority method sets a thread's priority to a value of 5 — the Thread.NORM_PRIORITY" -http://www.wilsonmar.com/1threads.htm
Keyword to use on member variables to force individual threads to re-read the variable's value from shared memory on every access and write back as soon as changes occur (prevents caching)
"Interrupting a thread means stopping what it is doing before it has completed its task, effectively aborting its current operation. Whether the thread dies, waits for new tasks, or goes on to the next step depends on the application."
"the method Thread.interrupt() does not interrupt a running thread. What the method actually does is to throw an interrupt if the thread is blocked, so that it exits the blocked state. More precisely, if the thread is blocked at one of the methods Object.wait, Thread.join, or Thread.sleep, it receives an InterruptedException, thus terminating the blocking method prematurely."
"The best, recommended way to interrupt a thread is to use a shared variable to signal that it must stop what it is doing. The thread must check the variable periodically, especially during lengthy operations, and terminate its task in an orderly manner...Just be sure to declare the shared variable as volatile or enclose any access to it into synchronized blocks/methods."
"But what happens if the thread is blocked waiting for some event?" It won't hit your exit-test. Solution: Interrupt the thread with Thread.interrupt(). If the thread is blocked at one of the methods Object.wait, Thread.join, or Thread.sleep, it receives an InterruptedException, thus terminating the blocking method prematurely (does nothing if thread is not blocked). Then you can test the shared variable and stop.
"But what happens if the thread is blocked on an I/O operation? I/O can block a thread for a considerable amount of time, particularly if network communication is involved. in Java 1.4, the blocked thread will get a ClosedByInterruptException exception....Or call the close() method of the socket the thread is blocked in. In this case, if the thread is blocked in an I/O operation, the thread will get a SocketException exception, much like the interrupt() method causes an InterruptedException to be thrown. The only caveat is that a reference to the socket must be available so that its close() method can be called. That means the socket object must also be shared."
"Thread.stop method: Although it indeed stops a running thread, the method is unsafe and was deprecated"
From: http://builder.com.com/5100-6370_14-5144546.html (link no longer valid)