# Exercise 1.4: Resolving the thread bottleneck

Before you begin, you must complete Exercise 1.3: Identifying a thread bottleneck.

To locate the deadlock in your code, you can use the the UML2 Sequence Diagram (the Object Interactions and Thread Interactions views) and the Call Stack profiling resource in the Profiling Monitor, in addition to the Thread View.

To resolve this deadlock, let's first find out which method calls and which objects are involved in the problem:

1. In the Thread View, find the first `philo*` thread that enters a "Waiting for Lock" state. Pause your cursor over the "Waiting for Lock" segment. The tool tip identifies the lock that the thread is waiting for: `Fork.<id number>`.
2. Right-click the Profiling resource for the run, and select Open With > UML2 Object Interactions. The UML2 Sequence Diagram view opens, displaying Object Interactions.
3. In the sequence diagram, scroll the view to find `Fork.<id number>`, and double-click to select it.
4. Scroll down to find a horizontal arrow from one of the `philo*` threads to `Fork.<id number>`. These arrows show interactions between objects, and the first interaction between these two objects will indicate that the `philo*` thread has acquired `Fork.<id number>`. You'll find such an arrow labeled `getName`.
5. Double-click `getName`. In the Thread View, the vertical Current Time indicator moves to show to see what was happening in the entire program when `getName` was called. You can see that the request was successful, as the `philo*` thread that is making the request does not enter the "Waiting for Lock" state.
6. In the sequence diagram, double-click `Fork.<id number>` again, and scroll down to find a `getName` request that originated in a different `philo*` thread.
7. Double-click this instance of `getName`. The Current Time indicator will show that the `philo*` thread making the request does not get `Fork.<id number>`, and enters a "Waiting for Lock" state.

In this instance, a request for a Fork that is held by another thread is the problem. Check other threads that end in the "Waiting for Lock" state to verify that this is true in other instances as well.

Now let's try to find the method that is causing the problem:

1. Right-click the Profiling resource for the run, and select Open With > UML2 Thread Interactions. The UML2 Sequence Diagram view opens, displaying Thread Interactions.
2. In the Profiling Monitor, expand your Profiling resource, then the Thread Analysis entry and the Call Stack entry.
3. In the Thread View, where the names of threads are displayed, double-click the first of the `philo*` threads that enters the "Waiting for Lock" state. Notice that the Thread Interactions view changes to display information for only that thread.
4. Scroll down to the end of the information for the thread, and double click the last method that the thread ran: the `run` method. The Call Stack in the Profiling Monitor displays all the calls on the stack at that time.
5. In the Call Stack, note that the thread that is holding the lock has called the `Sleep` method in `Philosopher.java`; or that it is also waiting for a lock and consequently doing nothing.
6. Check the other threads that end the run waiting for a lock; the `Sleep` method in `Philosopher.java` is often in the Call Stack, and may be the problem.

We now suspect the `Sleep` method. Let's have a look at the code:

1. In the Call Stack, right-click an instance of `Sleep(int) void [Philosopher.java]` and select Open source. The source opens in the editor, at the location of the `Sleep` class.
2. Examine the code. Note that the `Sleep` method is called from within the `run` method. There is first a call to `trace`, which prints out the message "got left...", and then a call to `Sleep`. By commenting out the call to `Sleep`, we can possibly prevent the deadlock.
3. Comment out `Sleep`.
4. Select File > Save.

Now profile your program again.

This time it runs without a deadlock, and writes to the console:

    HeadWaiter reports all philosophers have finished dining normally

As you can see, the Thread View and the other views show you what happens to the threads as your program runs. It's up to you to perform the analysis and resolve the deadlock, based on your knowledge of your program.

Finish your tutorial by reviewing the materials in the Summary.

Terms of use | Feedback
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.