Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.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 使用ReentrantLock避免死锁_Java_Multithreading_Thread Safety_Locking - Fatal编程技术网

Java 使用ReentrantLock避免死锁

Java 使用ReentrantLock避免死锁,java,multithreading,thread-safety,locking,Java,Multithreading,Thread Safety,Locking,我在做一些练习作业,并尝试使用一些虚拟代码来更好地理解线程和锁的概念。下面是一段(有时)陷入死锁的代码 A.java B.java Demo.java 解决方案:我使用了锁s而不是同步 A.java B.java 进行上述更改后,代码不会导致死锁。这是实现这一点的正确方法吗(基本上,我希望查看impendingExecute()方法)?另外,(有点偏离评论)有没有我能遇到的真实场景 注意:我已经在代码审查上发布了这个问题,但似乎虚拟代码的审查是离题的。您可以使用java.util.concurr

我在做一些练习作业,并尝试使用一些虚拟代码来更好地理解线程和锁的概念。下面是一段(有时)陷入死锁的代码

A.java

B.java

Demo.java

解决方案:我使用了
s而不是
同步

A.java

B.java

进行上述更改后,代码不会导致死锁。这是实现这一点的正确方法吗(基本上,我希望查看
impendingExecute()
方法)?另外,(有点偏离评论)有没有我能遇到的真实场景


注意:我已经在代码审查上发布了这个问题,但似乎虚拟代码的审查是离题的。

您可以使用java.util.concurrent.locks.ReentrantLock。这种设计允许该方法尝试获取这两个类的锁,如果失败则释放锁,必要时稍后重试。如果您需要尝试直到成功,那么您需要将它放入一个循环中,并以某种策略终止

while (true) {
    if (this.lock.tryLock()) {
        try {
          if (ba.lock.tryLock()) {
            try {
             //some logic
              break;
            } finally {
              ba.lock.unlock();
            }
          }
        } finally {
          this.lock.unlock();
        }
    }
    int n = number.nextInt(1000);
    int TIME = 1000 + n; // 1 second + random delay to prevent livelock
    Thread.sleep(TIME);
}
或者,您可以使用此解决方案,确保以相同的顺序获取和释放多个锁:

if (compareTo(ba) < 0) {
        former = this;
        latter = ba;
    } else {
        former = ba;
        latter = this;
    }
    synchronized (former) {
        synchronized (latter) {
            //Some logic
        }
    }
}
if(与(ba)<0相比){
前者=此;
后者=ba;
}否则{
前者=ba;
后者=这个;
}
同步(前){
同步(后者){
//一些逻辑
}
}
}

感谢您的及时回复:)
public class Demo {
    public static void main(String[] args) {
    A a = new A();
    B b = new B();

    a.setB(b);
    b.setA(a);

    new Thread(() -> {
        a.foo(true);
    }).start();

    new Thread(() -> {
        b.bar(true);
    }).start();
    }
}
public class A {

    private final ReentrantLock lock = new ReentrantLock();
    private B b;

    public void setB(B b) {
        this.b = b;
    }

    public ReentrantLock lock() {
        return lock;
    }

    public boolean impendingExecute() {
        Boolean thisLock = false;
        Boolean otherLock = false;
        try {
            thisLock = lock.tryLock();
            otherLock = b.lock().tryLock();
        } finally {
            if (!(thisLock && otherLock)) {
                if (thisLock) {
                    lock.unlock();
                }
                if (otherLock) {
                    b.lock().unlock();
                }
            }
        }
        return thisLock && otherLock;
    }

    public void foo(boolean callBar) {
        System.out.println("foo");
        if (callBar && impendingExecute()) {
            try {
                b.bar(false);
            } finally {
                lock.unlock();
                b.lock().unlock();
            }
        }
    }
}
public class B {

    private final ReentrantLock lock = new ReentrantLock();
    private A a;

    public void setA(A a) {
        this.a = a;
    }

    public ReentrantLock lock() {
        return lock;
    }

    public boolean impendingExecute() {
        Boolean thisLock = false;
        Boolean otherLock = false;
        try {
            thisLock = lock.tryLock();
            otherLock = a.lock().tryLock();
        } finally {
            if (!(thisLock && otherLock)) {
                if (thisLock) {
                    lock.unlock();
                }
                if (otherLock) {
                    a.lock().unlock();
                }
            }
        }
        return thisLock && otherLock;
    }

    public void bar(boolean callFoo) {
        System.out.println("bar");
        if (callFoo && impendingExecute()) {
            try {
                a.foo(false);
            } finally {
                lock.unlock();
                a.lock().unlock();
            }
        }
    }
}
while (true) {
    if (this.lock.tryLock()) {
        try {
          if (ba.lock.tryLock()) {
            try {
             //some logic
              break;
            } finally {
              ba.lock.unlock();
            }
          }
        } finally {
          this.lock.unlock();
        }
    }
    int n = number.nextInt(1000);
    int TIME = 1000 + n; // 1 second + random delay to prevent livelock
    Thread.sleep(TIME);
}
if (compareTo(ba) < 0) {
        former = this;
        latter = ba;
    } else {
        former = ba;
        latter = this;
    }
    synchronized (former) {
        synchronized (latter) {
            //Some logic
        }
    }
}