Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可重入锁定始终通过同一线程锁定和解锁_Java_Multithreading_Reentrantlock - Fatal编程技术网

Java 可重入锁定始终通过同一线程锁定和解锁

Java 可重入锁定始终通过同一线程锁定和解锁,java,multithreading,reentrantlock,Java,Multithreading,Reentrantlock,我试图在多线程上实现可重入锁,但由于某些原因,同一线程解锁,然后再次锁定,导致始终运行同一线程,因此执行相同的操作 下面是如何生成线程的代码 IntStream.range(0,(NUMBER_OF_THREADS)).forEach(index ->{ boolean operation = (index % 2 == 0) ? true : false; Thread t = new Thread(new Client(operation

我试图在多线程上实现可重入锁,但由于某些原因,同一线程解锁,然后再次锁定,导致始终运行同一线程,因此执行相同的操作

下面是如何生成线程的代码

IntStream.range(0,(NUMBER_OF_THREADS)).forEach(index ->{
            boolean operation = (index % 2 == 0) ? true : false;
            Thread t = new Thread(new Client(operation,this));
            t.start();
});
下面是线程的run函数是如何工作的

@Override
public void run() {
    while(!Thread.interrupted()) {
        System.out.println("Trying to acquire lock : " + main.getLock().tryLock()
                + " thread id " + Thread.currentThread().getName());
       // if (main.getLock().tryLock()) {
        try {
            main.getLock().lock();
            if(main.getLock().isHeldByCurrentThread()) {
                System.out.println("Lock held by this thread " + main.getLock().isHeldByCurrentThread()
                        + " thread id : " + Thread.currentThread().getName());
                if (operation) {
                    main.getcAaccount().deposit(1);
                } else {
                    main.getcAaccount().withdraw(2);
                }
                Thread.currentThread().sleep(3000);
            }
        } catch (InterruptedException e) {
                e.printStackTrace();
        } finally {
            System.out.println("Thread id : " + Thread.currentThread().getName() + " unlocking");
            main.getLock().unlock();//always have the unlock part here to ensure it unlock
        }
}
它正确地打印出其他5个线程正在尝试获取锁并失败,然后线程id…正在解锁…并且立即相同的线程再次锁定,即使它应该处于休眠状态

在这个逻辑场景中,我错过了什么吗

先谢谢你

编辑建议修复的屏幕截图。

重新进入需要在每次锁定后进行后续解锁。例如,如果我调用了三次
lock.lock()
,那么我也会调用三次
lock.unlock()
。<代码> ReentrantLock <代码>不会认为自己在这个事件发生之前解锁。

您没有意识到的是,如果成功的话,
lock.tryLock()
,本质上就像调用
lock.lock()
。因此,通过两次
lock
ing,您还需要两次
unlock
。在代码示例中,您只解锁一次,因此最初锁定的线程在技术上仍然拥有锁

修复它应该很简单,您可以从代码中删除第二个
lock.lock()
,互斥应该仍然有效。或者,如果需要锁定阻塞,则将
lock.tryLock()
替换为
lock.lock()


根据您的编辑,您解决了一个删除额外锁的问题,但现在您遇到了时间问题。您实际上不需要
tryLock
。您可以将其替换为
lock
,因为
lock
调用将挂起线程并在锁已被持有时阻塞(最终在调用解锁时唤醒)。

您的目标是什么?您想实现什么?当您已经通过
tryLock()
获得锁时,为什么要调用
lock()
?阻止并发,其中一个线程存放,另一个线程绘制,但顺序并不重要。我只是不明白为什么同一个线程解锁,然后在它应该处于休眠状态时获得锁。我已经按照你说的做了,但仍然存在相同的问题。我会用你建议的补丁编辑一个截图。好的,那么你就遇到了时间问题。请考虑我的第二点:用<代码>锁定< /代码>替换<代码> TyyLoo< /Cord>。无需
睡眠
,因为线程将被阻塞在
lock()
上。我删除了if(lock.tryLock()),现在只有同一个线程自己工作。奇怪的东西。我的意思是其他5个线程没有打印任何获取锁的尝试。我将为您发布更新的代码,您将tryLock替换为
lock.lock()
?哦,我的天啊,就像我常说的那样,是简单而愚蠢的事情破坏了复杂的东西。再次感谢你。就像一个符咒,不同的线程现在得到锁,循环在存款和取款之间以任意方式进行(无论哪个线程得到锁)。再次感谢您抽出时间。我投了赞成票,并接受了答案。