Glossary of terms
- critical code sections
- Code sequences that let multiple threads manipulate class and instance field variables and other shared resources.
- When multiple threads acquire each others' needed locks but can't release those locks because they are both waiting to enter their respective critical code sections.
- A software entity that a monitor uses to prevent multiple threads from entering the monitor.
- A protective wrapper around a critical code section.
- race condition
- The act of each thread racing to complete its critical code section before some other thread enters that critical code section.
- One-at-a-time ordering.
- shared variables
- Class and instance field variables.
- The act of serializing thread access to critical code sections.
Tips and cautions
These tips and cautions will help you write better programs and save you from agonizing over why the compiler produces error messages.
- When you need to determine if a thread holds a given object's associated lock, call
static boolean holdsLock(Object o)method. That method returns a Boolean true value if the thread calling that method holds the lock associated with the object that
oreferences; otherwise, false returns. For example, if you were to place
System.out.println (Thread.holdsLock (ft));at the end of
holdsLock()would return false. False would return because the main thread executing the
main()method does not use the synchronization mechanism to acquire any lock. However, if you were to place
System.out.println (Thread.holdsLock (ft));in either of
holdsLock()would return true because either the deposit thread or the withdrawal thread had to acquire the lock associated with the
ftreferences before that thread could enter its critical code section.
- To avoid a no-synchronization scenario, choose an object common to all relevant threads. That way, those threads will compete to acquire the same object's lock, and only one thread at a time can enter the associated critical code section.
- To avoid deadlock, carefully analyze your source code for situations where threads might attempt to acquire each others' locks, such as when a synchronized method calls another synchronized method. You must do that because a JVM cannot detect or prevent deadlock.
- Don't synchronize a thread object's
run()method because situations arise where multiple threads need to execute
run(). Because those threads attempt to synchronize on the same object, only one thread at a time can execute
run(). As a result, each thread must wait for the previous thread to terminate before it can access
Please answer the following two questions and complete the exercise:
- Can multiple threads access the same local variables or parameters? Why or why not?
- Why is synchronization important?
- The article cautions you about synchronizing the
run()method. Write a program that demonstrates why you should not synchronize that method.
Answers to last month's homework
Last month, I asked you two questions. My answers appear in red.
- What is a third benefit of multithreading?
Multithreading allows a processor to remain productive because the processor does not need to spend all its time waiting for input/output operations to complete.
- Internally, the
wait(0)instead of the
sleep(long millis)method. Why?
wait()methods cause a thread to lose the monitor's ownership. In contrast,
sleep()methods do not cause a thread to lose monitor ownership. That implies threads retain any held locks when they call the
join()was coded to call a
sleep()method, two threads calling that method might deadlock (because they might hold each other's locks). By having
wait(0), Sun has eliminated that deadlock potential.