Java 协作对象之间的死锁

Java 协作对象之间的死锁,java,multithreading,Java,Multithreading,在实践中查看Java并发时我遇到了下面的代码死锁,它演示了在协作对象之间如何发生死锁。如果一个线程调用getImage(),而另一个线程同时调用setLocation(),则可能会由于锁顺序而导致死锁。为了解决这个问题,我们使用下面的打开调用无死锁。我的疑问在于setLocation()中的无死锁为什么我们要在已同步的方法中再次执行同步(此)?synchronized方法不是已经在上synchronized了吗?我们如何使用第二个示例来防止死锁 死锁 class Taxi { @

在实践中查看
Java并发时
我遇到了下面的代码死锁,它演示了在
协作对象之间如何发生
死锁
。如果一个线程调用
getImage()
,而另一个线程同时调用
setLocation()
,则可能会由于
锁顺序而导致死锁。为了解决这个问题,我们使用下面的
打开调用
无死锁。我的疑问在于
setLocation()
中的无死锁为什么我们要在已同步的
方法中再次执行
同步(此)
synchronized
方法不是已经在
synchronized
了吗?我们如何使用第二个示例来防止死锁

死锁

class Taxi {
        @GuardedBy("this")
        private Point location, destination;
        private final Dispatcher dispatcher;

        public Taxi(Dispatcher dispatcher) {
            this.dispatcher = dispatcher;
        }

        public synchronized Point getLocation() {
            return location;
        }

        public synchronized void setLocation(Point location) {
            this.location = location;
            if (location.equals(destination))
                dispatcher.notifyAvailable(this);
        }
    }

    class Dispatcher {
        @GuardedBy("this")
        private final Set<Taxi> taxis;
        @GuardedBy("this")
        private final Set<Taxi> availableTaxis;

        public Dispatcher() {
            taxis = new HashSet<Taxi>();
            availableTaxis = new HashSet<Taxi>();
        }

        public synchronized void notifyAvailable(Taxi taxi) {
            availableTaxis.add(taxi);
        }

        public synchronized Image getImage() {
            Image image = new Image();
            for (Taxi t : taxis)
                image.drawMarker(t.getLocation());
            return image;
        }
    }
class Taxi {
        @GuardedBy("this")
        private Point location, destination;
        private final Dispatcher dispatcher;

        public synchronized Point getLocation() {
            return location;
        }

        public synchronized void setLocation(Point location) {
            boolean reachedDestination;
            synchronized (this) {
                this.location = location;
                reachedDestination = location.equals(destination);
            }
            if (reachedDestination)
                dispatcher.notifyAvailable(this);
        }
    }

    class Dispatcher {
        @GuardedBy("this")
        private final Set<Taxi> taxis;
        @GuardedBy("this")
        private final Set<Taxi> availableTaxis;

        public synchronized void notifyAvailable(Taxi taxi) {
            availableTaxis.add(taxi);
        }

        public Image getImage() {
            Set<Taxi> copy;
            synchronized (this) {
                copy = new HashSet<Taxi>(taxis);
            }
            Image image = new Image();
            for (Taxi t : copy)
                image.drawMarker(t.getLocation());
            return image;
        }
    }
class出租车{
@担保人(“本”)
专用点位置、目的地;
专用最终调度员;
公共出租车(调度员){
this.dispatcher=dispatcher;
}
公共同步点getLocation(){
返回位置;
}
公共同步无效设置位置(点位置){
这个位置=位置;
if(位置等于(目的地))
dispatcher.notifyAvailable(此);
}
}
类调度器{
@担保人(“本”)
私人终端机的士;
@担保人(“本”)
专用最终设置可用性轴;
公共调度程序(){
taxis=新HashSet();
availableTaxis=新HashSet();
}
可使用公共交通工具(出租车){
可用轴添加(滑行);
}
公共同步映像getImage(){
图像=新图像();
出租车(t:出租车)
image.drawMarker(t.getLocation());
返回图像;
}
}
无死锁

class Taxi {
        @GuardedBy("this")
        private Point location, destination;
        private final Dispatcher dispatcher;

        public Taxi(Dispatcher dispatcher) {
            this.dispatcher = dispatcher;
        }

        public synchronized Point getLocation() {
            return location;
        }

        public synchronized void setLocation(Point location) {
            this.location = location;
            if (location.equals(destination))
                dispatcher.notifyAvailable(this);
        }
    }

    class Dispatcher {
        @GuardedBy("this")
        private final Set<Taxi> taxis;
        @GuardedBy("this")
        private final Set<Taxi> availableTaxis;

        public Dispatcher() {
            taxis = new HashSet<Taxi>();
            availableTaxis = new HashSet<Taxi>();
        }

        public synchronized void notifyAvailable(Taxi taxi) {
            availableTaxis.add(taxi);
        }

        public synchronized Image getImage() {
            Image image = new Image();
            for (Taxi t : taxis)
                image.drawMarker(t.getLocation());
            return image;
        }
    }
class Taxi {
        @GuardedBy("this")
        private Point location, destination;
        private final Dispatcher dispatcher;

        public synchronized Point getLocation() {
            return location;
        }

        public synchronized void setLocation(Point location) {
            boolean reachedDestination;
            synchronized (this) {
                this.location = location;
                reachedDestination = location.equals(destination);
            }
            if (reachedDestination)
                dispatcher.notifyAvailable(this);
        }
    }

    class Dispatcher {
        @GuardedBy("this")
        private final Set<Taxi> taxis;
        @GuardedBy("this")
        private final Set<Taxi> availableTaxis;

        public synchronized void notifyAvailable(Taxi taxi) {
            availableTaxis.add(taxi);
        }

        public Image getImage() {
            Set<Taxi> copy;
            synchronized (this) {
                copy = new HashSet<Taxi>(taxis);
            }
            Image image = new Image();
            for (Taxi t : copy)
                image.drawMarker(t.getLocation());
            return image;
        }
    }
class出租车{
@担保人(“本”)
专用点位置、目的地;
专用最终调度员;
公共同步点getLocation(){
返回位置;
}
公共同步无效设置位置(点位置){
布尔到达目的地;
已同步(此){
这个位置=位置;
到达目的地=位置。等于(目的地);
}
如果(到达目的地)
dispatcher.notifyAvailable(此);
}
}
类调度器{
@担保人(“本”)
私人终端机的士;
@担保人(“本”)
专用最终设置可用性轴;
可使用公共交通工具(出租车){
可用轴添加(滑行);
}
公共映像getImage(){
设置副本;
已同步(此){
复制=新哈希集(出租车);
}
图像=新图像();
出租车(t:复印件)
image.drawMarker(t.getLocation());
返回图像;
}
}

由于getImage未同步,因此秒内没有死锁,因此调用getLocation时没有锁。关于同步(此)内部设置位置,您是对的,它没有任何用途