Livelock in java

herosoft發表於2010-03-03

Recently I read the chapter of concurrency in the book of <>. It mentions the concurency problems of starvation and livelock, which are much less common a problem than deadlock, but problems that every designer of concurrent software is likely to encounter.
Then I tried to find out some code snippet example of starvaton and livelock, but unexpectedly, there is not any code snippet at all from the top2 result pages returned by goggle and baidu search engine. Therefore, I have to implement them all by myself. Here is the reference and code example.

http://java.sun.com/docs/books/tutorial/essential/concurrency/starvelive.html

Livelock

A thread often acts in response to the action of another thread. If the other thread's action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked — they are simply too busy responding to each other to resume work. This is comparable to two people attempting to pass each other in a corridor: Alphonse moves to his left to let Gaston pass, while Gaston moves to his right to let Alphonse pass. Seeing that they are still blocking each other, Alphone moves to his right, while Gaston moves to his left. They're still blocking each other, so...

[@more@]

package com.herosoft.Concurrency;

public class LiveLock {

static class Corridor {
static volatile boolean[][] passage = new boolean[2][2];
}

public static Object lock = new Object();
public static volatile boolean notWaited = true;
public static volatile boolean f = false;

interface Movement {
void move();
}

public static volatile boolean finished;

static class WalkingMan extends Thread {
public String name;
public int pos;
private WalkingMan theOpposingSide;
public boolean moved;
public WalkingMan(String name, int pos) {
this.name=name;
this.pos =pos;
}
public void setTheOpposingSide (WalkingMan m) {
theOpposingSide=m;
}
public void sync(Movement m) {
if(pos==0) {
//f=false;
synchronized(lock) {
notWaited=false;
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
m.move();
finished=true;
synchronized(lock) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
f=true;
}
else {

while(notWaited)
try {
sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

f=false;
while(!finished) {
if(!moved) {
m.move();
moved=true;
}

synchronized(lock) {
if(!finished)
lock.notify();
}
}
finished=false;
moved=false;
notWaited=true;


while(true)
synchronized(lock) {
if(notWaited&&!f) {
lock.notify();

}else
break;
}

//f=false;
}
}
public void run() {
while(true) {
if(pos == 0) {
if(Corridor.passage[pos][0]&&Corridor.passage[1][0]) {
//System.out.println(name + " sees that someone blocks his way, so he moves to left");

sync(new Movement() {
public void move() {
Corridor.passage[pos][0]=false;
Corridor.passage[pos][1]=true;
System.out.println(name + " sees that someone blocks his way, so he moves to left");
}
});

}
else if(Corridor.passage[pos][1]&&Corridor.passage[1][1]) {
//System.out.println(name + " sees that someone blocks his way, so he moves to right");

sync(new Movement() {
public void move() {
Corridor.passage[pos][1]=false;
Corridor.passage[pos][0]=true;
System.out.println(name + " sees that someone blocks his way, so he moves to right");
}
});
} else{
System.out.println(name + " passed the corridor");
for(int i = 0; i < Corridor.passage.length; i++) {
for(int j=0; j < Corridor.passage[i].length; j++)
System.out.print(Corridor.passage[i][j]);
System.out.println();
}
System.out.println("finished:"+finished+"moved:"+moved+"notWaited:"+notWaited+"f:"+f);
break;
}
}
else if(pos == 1){
if(Corridor.passage[pos][0]&&Corridor.passage[0][0]) {
//System.out.println(name + " sees that someone blocks his way, so he moves to right");


sync(new Movement() {
public void move() {
Corridor.passage[pos][0]=false;
Corridor.passage[pos][1]=true;
System.out.println(name + " sees that someone blocks his way, so he moves to right");
}
});

}
else if(Corridor.passage[pos][1]&&Corridor.passage[0][1]) {
//System.out.println(name + " sees that someone blocks his way, so he moves to left");


sync(new Movement() {
public void move() {
Corridor.passage[pos][1]=false;
Corridor.passage[pos][0]=true;
System.out.println(name + " sees that someone blocks his way, so he moves to left");
}
});

} else{
System.out.println(name + " passed the corridor");
for(int i = 0; i < Corridor.passage.length; i++) {
for(int j=0; j < Corridor.passage[i].length; j++)
System.out.print(Corridor.passage[i][j]);
System.out.println();
}
System.out.println("finished:"+finished+"moved:"+moved+"notWaited:"+notWaited+"f:"+f);
break;
}
}

}
}
}

/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub

WalkingMan m1 = new WalkingMan("Alphonse", 0);
Corridor.passage[0][0]=true;
System.out.println(m1.name + " stands on his right");
WalkingMan m2 = new WalkingMan("Gaston", 1);
Corridor.passage[1][0]=true;
System.out.println(m2.name + " stands on his left");
m1.setTheOpposingSide(m2);
m2.setTheOpposingSide(m1);
System.out.println(m1.name + " meets " + m2.name + " at the opposite in the corridor");

m1.start();
m2.start();
m1.join();//main thread never stops
m2.join();

}

}

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/220284/viewspace-1031578/,如需轉載,請註明出處,否則將追究法律責任。

相關文章