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时没有锁。关于同步(此)内部设置位置,您是对的,它没有任何用途