IntelliJ Community . CommonThreadingIssues

 
CommonThreadingIssues 

HOME INDEX SEARCH CHANGES GO  

Common Threading Issues In Java.

Deadlock

A simple definition of deadlock is that a system is deadlocked if two or more threads are waiting for two or more locks to to be freed and the system is such that the locks will never be freed.

The classic example of deadlock is the dining philosophers. The idea is that there are a bunch of philosophers sitting around a table. There is a bowl of rice in fron of each philosopher, and a single chopstick between each philosopher. A philosopher must have two chopsticks in order to eat. Once a philosopher has eaten, they put down both chopsticks so that another can eat.

The problem is that if each philosopher picks up the chopstick on the left, then no philosopher will be able to get to chopsticks, so they will literally starve because of deadlock smile

Below are some rules of thumb that help avoid deadlock:

  • Avoid having synchronized methods calling other synchronized methods.
  • Unfortunately, this is impractical, lots of Java methods are synchronized.

  • Actually if the synchronized method that is being called from a synchronized method does not call another synchronized method, then deadlock cannot occur (Is this true?)
  • Lock a "larger" object that is related to a set of smaller objects that need locks.

  • A gross example would be to lock all the data structures in a system with one lock. Unfortunately, this could prevent other threads from doing useful work.

  • Always acquire locks in the same order.

  • This can be tricky to implement, but the idea is that you have a lock hierarchy where each lock has only one parent and only one child. To try to acquire a lock, you must have the parent lock first. Unfortunately, there is no support in Java for this, it is up to the programmer.

  • Lock Starvation

    CPU starvation occurs when a thread never becomes the currently running thread. A thread can starve if it has a lower priority than the other threads and it never becomes the current thread. CPU starvation is usually a scheduling issue that occurs because the scheduler does not increase the priority of a thread that has not run on the CPU.
    Lock starvation occurs when a thread becomes the currently running thread, but the thread never obtains a lock it needs because another thread is holding the lock.

    Lock starvation is rare, each of the points must be true:

  • More than one thread must be trying to acquire the same lock.

  • The intermediate results during lock contention are of interest.
  • If we are only interested in the final results, then we don't really care if some of the threads are starved of the lock. Eventually all the threads will get the lock, and we will get our results.
  • The threads must have the same priority.

  • A round-robin scheduler must be controlling the threads.
  • If the threads are not under a round-robin scheduler, then we will have CPU starvation, not lock starvation.
  • We get lock starvation because:

  • Lock acquisitions do not queue - If thread is attempting to acquire a lock, it does not check to see if another thread has tried to acquire the lock and failed.

  • When a lock is released, the current thread may or may not continue to be the current thread.
  • Priorities

    The Java Specification, section 17.12 says that Thread priorities are a preference:

    Every thread has a priority. When there is competition for processing resources, threads with higher priority are generally executed in preference to threads with lower priority. Such preference is not, however, a guarantee that the highest priority thread will always be running, and thread priorities cannot be used to reliably implement mutual exclusion.

    So, be careful about using priorities.

    Priority Inversion

    Another subtle problem is priority inversion, for which I need to find a good description.

    Swing

    In Swing, components should only be accessed from the event-dispatching thread.

    Resourced

  • Javasoft Swing Tutorial: Threads and Swing

  • ArticleIndex in the Swing Connection contains a few articles about Threads and Swing.
  • Common Thread Code Fragments

    Below are some common thread code fragments that appear over and over again.

    Starting a thread

    In an applet, the code below will start a thread
    public void start() {
        if (_plotThread == null) {
            _plotThread = new Thread(this, "Plot");
            _plotThread.start();
        }
    }    
    
    

    If the thread is null, then either the thread was never started, or started and stopped. If the thread is null, we create a new thread and start it. If the thread is not null in an applet, then we have already started the thread

    Stopping a thread

    public void stop () {
       _plotThread = null;
    }
    

    We set the thread to null here, but we could just call

    _plotThread.stop(). The Javasoft Thread tutorial says that stopping a thread is rather drastic, if the thread is doing something critical, then the applet might be left in an inconsistant state. Calling stop on a thread can be somewhat like hitting Control-C on a program - the program might not cleanup properly before exiting.

    Applets that use threads should implement the stop() method so that when the user moves to another page the applet stops. This is especially important for threads that produce sound or consume cpu cycles. See the Javasoft tutorial applet checklist for more information.

    Running

    public void run () {
        while (Thread.currentThread() == _plotThread) {
            repaint();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e){
        }
    }
    
    Here, we check to see if the _plotThread has been set to null by stop(). If it is not null, then we call repaint, and sleep for one second.

    When we sleep, other threads can run.

    -- CharltonBarreto - 27 Jun 2004

    e d i t a t t a c h r e f - b y d i f f s m o r e
    Have ideas, requests, problems regarding this site? Send feedback.
    Copyright © 2000-2003 by the contributing authors. All materials at intellij.org are the property of the contributing authors.