Bow / BowBack线程锁解释

时间:2015-08-15 12:00:26

标签: java multithreading

关于这个https://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html

我们有Bow / BowBack的例子,我无法理解,我想详细解释实际发生的事情

确实我删除了一些我不理解其目的的行:

    if (! (myLock && yourLock)) {
        if (myLock) {
             lock.unlock();
        }
        if (yourLock) {
             bower.lock.unlock();
        }
    }

它仍然有效!

获取锁定然后释放它的目的是什么,

在做这份工作之前?然后在完成工作后再次释放!!

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;    
public class Safelock {
    static class Friend {
        private final String name;
        private final Lock lock = new ReentrantLock();    
        public Friend(String name) {
            this.name = name;
        }    
        public String getName() {
            return this.name;
        }    
        public boolean impendingBow(Friend bower) {
            Boolean myLock = false;
            Boolean yourLock = false;
            try {
                myLock = lock.tryLock();
                yourLock = bower.lock.tryLock();
            } finally {
                if (! (myLock && yourLock)) {
                    if (myLock) {
                        lock.unlock();
                    }
                    if (yourLock) {
                        bower.lock.unlock();
                    }
                }
            }
            return myLock && yourLock;
        }                
        public void bow(Friend bower) {
            if (impendingBow(bower)) {
                try {
                    System.out.format("%s: %s has"
                        + " bowed to me!%n", 
                        this.name, bower.getName());
                    bower.bowBack(this);
                } finally {
                    lock.unlock();
                    bower.lock.unlock();
                }
            } else {
                System.out.format("%s: %s started"
                    + " to bow to me, but saw that"
                    + " I was already bowing to"
                    + " him.%n",
                    this.name, bower.getName());
            }
        }    
        public void bowBack(Friend bower) {
            System.out.format("%s: %s has" +
                " bowed back to me!%n",
                this.name, bower.getName());
        }
    }    
    static class BowLoop implements Runnable {
        private Friend bower;
        private Friend bowee;    
        public BowLoop(Friend bower, Friend bowee) {
            this.bower = bower;
            this.bowee = bowee;
        }        
        public void run() {
            Random random = new Random();
            for (;;) {
                try {
                    Thread.sleep(random.nextInt(10));
                } catch (InterruptedException e) {}
                bowee.bow(bower);
            }
        }
    }
    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new BowLoop(alphonse, gaston)).start();
        new Thread(new BowLoop(gaston, alphonse)).start();
    }
}

2 个答案:

答案 0 :(得分:1)

如果线程成功获取锁(或已经拥有锁),则

tryLock()返回true。您不理解的代码尝试获取两个朋友锁。如果至少无法获得其中一个:

if (! (myLock && yourLock)) {

然后它释放获得的那个(如果有的话):

    if (myLock) {
         lock.unlock();
    }
    if (yourLock) {
         bower.lock.unlock();
    }

因为如果两个锁都被成功获得,并且返回false,并且如果两个锁都没有成功获得,则返回false,并且不保持任何锁,则该方法的全部要点是返回true。

答案 1 :(得分:0)

finally块总是在try块中发生某些运行时异常时执行。它用于确保java程序(在这种情况下特别是锁,但它也经常用于关闭流)处于“有效”状态,退出try - catch - {{1}阻止。

在这种情况下,正如@JB Nizet发布的那样,目标是在获得两个锁时返回finally,并在没有获得锁时返回true。当 - 由于某些中断,只获得一个锁,程序不处于理想状态。 false块中的代码阻止了这一点:当只获得一个锁时,该锁就会被释放。