尝试使用ReetrantLock锁定/解锁时的Java线程锁定(true)

尝试使用ReetrantLock锁定/解锁时的Java线程锁定(true),java,multithreading,locking,deadlock,Java,Multithreading,Locking,Deadlock,我在一个应用程序中遇到了一些问题,该应用程序检查两个图像之间的差异,并根据百分比显示相似性 出于某种原因,我的输入线程读取“相似”的最小百分比调用了lock.lock(),而那个特定的线程只是无限期地死锁,但我似乎不明白为什么只有那个线程是死锁的 在下面的SSCCE中,在main方法main(String[])中,内联线程用于从控制台获取输入,如果我在其中键入任何数字,则会正确存储它,但只要它调用lock.lock()它会无限期地死锁,我不确定原因,因为ReetrantLock已被告知对调用线程

我在一个应用程序中遇到了一些问题,该应用程序检查两个图像之间的差异,并根据百分比显示相似性

出于某种原因,我的输入线程读取“相似”的最小百分比调用了
lock.lock()
,而那个特定的线程只是无限期地死锁,但我似乎不明白为什么只有那个线程是死锁的

在下面的SSCCE中,在main方法
main(String[])
中,内联
线程
用于从控制台获取输入,如果我在其中键入任何数字,则会正确存储它,但只要它调用
lock.lock()
它会无限期地死锁,我不确定原因,因为
ReetrantLock
已被告知对调用线程公平,并尝试在调用线程时订购它们

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;
}
private static volatile boolean running=false;
公共静态void main(字符串[]args)
{
webcam2 webcam=新的webcam2();
webcam.start();
(新线程(新可运行()
{
@凌驾
公开募捐
{
扫描仪=新的扫描仪(System.in);
(跑步时)
{
系统输出打印(“输入双精度:”;
double val=scanner.nextDouble();
lock.lock();//此处不确定地锁定
如果(val<0.0D)复位=真;
dif=val;
System.out.println(“搜索值:+dif”);
lock.unlock();
}
scanner.close();
}
})).start();
}
专用静态双dif=0.0D;
私有静态布尔重置=false;
私有静态ReentrantLock=新的ReentrantLock(true);
@凌驾
公开募捐
{
尝试
{
(跑步时)
{
//在窗口上显示图像
lock.lock();
如果(重置==真)
{
重置=错误;
lock.unlock();
doComplexStuffToImage();
}
lock.lock();
doComplexStuffToImage();
lock.unlock();
}
}
捕获(例外e)
{
e、 printStackTrace();
}
}
私有静态void doComplexStuffToImage()文件
{
尝试
{
睡眠(1000);
}
捕获(中断异常ie)
{
//吞咽异常
}
}
公开作废开始()
{
新线程(this.start();
运行=真;
}
公共停车场()
{
运行=错误;
}

一个线程正在锁定ReentrantLock,而不是释放它。“可重入”的意思是可以多次调用lock,但必须调用相同次数的unlock()。您锁定两次,然后解锁一次,这样您就不会真正解锁锁,因此没有其他进程获得机会。

哦,现在我看到了我的愚蠢错误,输入线程只有在调用重置时才能运行,但只有在其未锁定时才能调用。谢谢