プログラマメモ2 - programmer no memo2

ロックのサンプルをつくってみた 2006/06/06
2006/11/26

2006-06-23 ここの記事は厳密性に欠けています。

シーケンスが保たれない可能性があります。






こんなのつくってみた。

みそは、try{}finally{}

かならずfinallyを通る。



synchronizedをとると

実行のシーケンス

get lock

a

b

c

release lock

とはならない。







package quicklunch.jeu;



public class TestLock {



Lock lock;



public static void main(String[] args) {



final TestLock testLock = new TestLock();



Runnable runnable = new Runnable() {

public void run() {

try {

while (true) {

testLock.go();

Thread.sleep(1);

}

} catch (InterruptedException e) {



e.printStackTrace();

}

}

};

Thread thread1 = new Thread(runnable);

Thread thread2 = new Thread(runnable);

Thread thread3 = new Thread(runnable);

thread1.start();

thread2.start();

thread3.start();

}



public TestLock() {

this.lock = new Lock();

}



public void go() throws InterruptedException {

if (lock.isLocked()) {

return;

}

try {

lock.setLocked(true);

a();

b();

c();

} finally {

lock.setLocked(false);

}



}



public void a() {

System.out.println("process a " + Thread.currentThread());

}



public void b() throws InterruptedException {

System.out.println("process b " + Thread.currentThread());

Thread.sleep(0);

}



public void c() throws InterruptedException {

System.out.println("process c " + Thread.currentThread());

Thread.sleep(0);

//throw new RuntimeException("Wooooo");

}



class Lock {

boolean locked;



public synchronized boolean isLocked() {



return locked;

}



public synchronized void setLocked(boolean locked) {

if (locked) {

System.out.println("get lock!!" + Thread.currentThread());

} else {

System.out.println("release lock!!" + Thread.currentThread());

}



this.locked = locked;

}



}



}







sleepする時間が短いと、synchronizedがどういうふうに効いているかわからなくなる感じがする。

下記は、ロックをとるのと、チェックを同時にさせているので上のソースよりは厳密性がたかまっていると思う。





public class TestLock {



Lock lock;



public static void main(String[] args) {



final TestLock testLock = new TestLock();



Runnable runnable = new Runnable() {

public void run() {

try {

while (true) {

testLock.go();

Thread.sleep(0);

}

} catch (InterruptedException e) {



e.printStackTrace();

}

}

};

Thread thread1 = new Thread(runnable);

Thread thread2 = new Thread(runnable);

Thread thread3 = new Thread(runnable);

thread1.start();

thread2.start();

thread3.start();

}



public TestLock() {

this.lock = new Lock();

}



public void go() throws InterruptedException {

if (!lock.lock()) {

return;

}

try {

a();

b();

c();

} finally {

lock.release();

}



}



public void a() {

System.out.println("process a " + Thread.currentThread());

}



public void b() throws InterruptedException {

System.out.println("process b " + Thread.currentThread());

Thread.sleep(10);

}



public void c() throws InterruptedException {

System.out.println("process c " + Thread.currentThread());

Thread.sleep(70);

// throw new RuntimeException("Wooooo");

}



class Lock {

boolean locked;



public synchronized boolean lock() {

if (this.locked) {

return false;

}

System.out.println("get lock!!" + Thread.currentThread());

this.locked = true;

return true;

}



public synchronized void release() {

System.out.println("release lock!!" + Thread.currentThread());

this.locked = false;

}



}



}

: