2005年2月17日
DeadLockはよくJava入門書に書いてあるが、LiveLockはほとんど書かれていないので、擬似的に再現してみる。
デッドロックとは、スレッド1、スレッド2が存在した場合、相互にロックの取り合いを行い、処理が中断してしまうことである。ライブロックとは、スレッド1、スレッド2、スレッド3が存在した場合、スレッド1、スレッド2が交代してロックを取得することで全然スレッド3が処理を行わない状態を意味する。スレッド3自体は動作している、つまり生きている(Live)が餓死状態になっている。
/*
* 2005 Copyright satoshiokita All Right Reserved.
*/
package org.oklab.thread;
/**
* Live Lock Sample Program.
*
* @version 0.01
* @author satoshi okita
*
* 2005 Copyright satoshiokita All Right Reserved.
*/
public class LiveLock extends Thread {
private String runningMessage = null;
private ThreadState stateInstance = null;
public LiveLock(String runningMessage) {
super();
this.runningMessage = runningMessage;
/*
* instanciate default priority.
*/
stateInstance = new ThreadState();
}
public void setCustomPriority(int priority) {
stateInstance.setPriority(priority);
}
public int getCustomPriority() {
return (int) stateInstance.getPriority();
}
public void run() {
while (true) {
if (ThreadManager.exist(this) == true) {
stateInstance.incrementEnergyCounter();
}
long resultCalc = stateInstance.getEnergyCounter() % 10000;
if ((resultCalc % 10000) == 0 ) {
System.out.print(this.getName() +" : ");
System.out.println(
stateInstance.getEnergyCounter());
}
}
}
class ThreadState {
private long energyCounter;
private long priority;
public ThreadState() {
energyCounter = 100L;
priority = 1L;
}
public ThreadState(long priority) {
this.priority = priority;
}
public ThreadState(long energyCounter, long priority) {
this.energyCounter = energyCounter;
this.priority = priority;
}
public void setEnergyCounter(long energyCounter) {
this.energyCounter = energyCounter;
}
public long getEnergyCounter() {
return energyCounter;
}
public void incrementEnergyCounter() {
energyCounter++;
}
public void setPriority(long priority) {
this.priority = priority;
}
public long getPriority() {
return priority;
}
}
}
org.oklab.thread.ThreadManagerクラスの実装
/*
* 2005 Copyright satoshiokita All Right Reserved.
*/
package org.oklab.thread;
import java.util.Set;
import java.util.HashSet;
/**
* The Thread Manager automanically administrate LiveLock Thread.
*
* @version 0.01
* @author satoshi okita
*
* 2005 Copyright satoshiokita All Right Reserved.
*/
public class ThreadManager {
private static Set threadPool = new HashSet();
private static boolean setThread(Runnable implementThread)
throws Exception {
boolean checkExist = threadPool.add(implementThread);
if ( checkExist == false ) {
throw new Exception("pool has same thread.");
}
return checkExist;
}
public static boolean exist(Object object) {
return threadPool.contains(object);
}
/**
* Louncher.
* @param String []
*/
public static void main(String [] args) {
LiveLock thread1 = new LiveLock("1");
LiveLock thread2 = new LiveLock("2");
LiveLock thread3 = new LiveLock("3");
try {
ThreadManager.setThread(thread1);
ThreadManager.setThread(thread2);
// ThreadManager.setThread(thread3);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(ThreadManager.exist(thread1));
thread1.setCustomPriority(Thread.MAX_PRIORITY);
thread1.start();
System.out.println("debug:th1:" + thread1.getPriority());
thread2.setCustomPriority(Thread.MAX_PRIORITY);
thread2.start();
System.out.println("debug:th2:" + thread2.getPriority());
thread3.setCustomPriority(Thread.MIN_PRIORITY);
thread3.start();
System.out.println("debug:th3:" + thread3.getPriority());
}
}
このサンプルでは、LiveLockのインスタンスthread3が、ロックを取得できず飢餓状態に陥る。