user3045798
user3045798

Reputation: 193

Java thread lock when trying to lock/unlock with ReetrantLock(true)

I am having some trouble with a ReetrantLock(true) in an application that checks the difference between two images and shows similarity based on a percentage.

For some reason my input thread for reading in the minimum percent for being "similar" calls lock.lock() and that particular thread just deadlocks indefinitely but I can't seem to figure out why only that thread is deadlocking.

In the SSCCE below in the main method main(String[]) the inline Thread is used to get input from the console and if I type any number in it correctly stores it but as soon as it calls lock.lock() it deadlocks indefinitely and I am unsure why because the ReetrantLock has been told to be fair to caller threads and try to order them for when they called.

private static volatile boolean running = false;

public static void main(String[] args)
{
    webcam2 webcam = new webcam2();
    webcam.start();
    (new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            Scanner scanner = new Scanner(System.in);
            while (running)
            {
                System.out.print("Enter Double: ");
                double val = scanner.nextDouble();
                lock.lock(); // locks indefinatly here
                if (val < 0.0D) reset = true;
                dif = val;
                System.out.println("Searching for value: " + dif);
                lock.unlock();
            }
            scanner.close();
        }
    })).start();
}

private static double dif = 0.0D;
private static boolean reset = false;
private static ReentrantLock lock = new ReentrantLock(true);

@Override
public void run()
{
    try
    {
        while (running)
        {
                // show image on window
                lock.lock();
                if (reset == true)
                {
                    reset = false;
                    lock.unlock();
                    doComplexStuffToImage();
                }
                lock.lock();
                doComplexStuffToImage();
                lock.unlock();
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

private static void doComplexStuffToImage()
{
    try
    {
        Thread.sleep(1000);
    }
    catch(InterruptedException ie)
    {
        //swallow exception
    }
}

public void start()
{
    new Thread(this).start();
    running = true;
}

public void stop()
{
    running = false;
}

Upvotes: 0

Views: 227

Answers (1)

Peter Lawrey
Peter Lawrey

Reputation: 533680

One thread is locking the ReentrantLock and not releasing it. What "reentrant" means is you can call lock many times, but you must call unlock() the same number of times. You lock twice, and unlock once so you are not actually unlocking the lock, thus no other process gets a chance.

Upvotes: 1

Related Questions