1. LockSample.java
- 인터럽트 요청이 올때까지 무식하게 자원만 축내는 넘..
package study.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockSample {

 final Lock lock = new ReentrantLock();
 
 public static Thread thread;
 
 public void lockTest() throws InterruptedException {
 
  if(!lock.tryLock(1, TimeUnit.SECONDS)) {
   System.out.println(Thread.currentThread().getName() + " : 누군가가 선점하고 있다.");
   return;
  }
 
  thread = Thread.currentThread();
 
  System.out.println(Thread.currentThread().getName() + " : 내가 선점하고 있다.");
 
  try {
     // 락을 인터럽트 시킬수 있다.
     lock.lockInterruptibly();
    
   try {
      // critical section
    Thread.sleep(6000);
     } finally {
      // 획 해제
      lock.unlock();
     }
   } catch (InterruptedException e) {
    // 인터럽트 됨.
  
    throw new InterruptedException(Thread.currentThread().getName() + " : 인터럽트 당함");
   }  finally {
    lock.unlock();
   }
 }
}

2. Task.java
- 무식하게 일만 시키는넘
package study.lock;


public class Task extends Thread {
 
 final LockSample sample;
 
 public Task(String name, final LockSample sample) {
  super(name);
  this.sample = sample;
 }
 
 public void run() {

  while(!isInterrupted())  {
   try {

    sample.lockTest();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    return;
   }
  }
 }
}

3. 테스트
final LockSample sample = new LockSample();
 
Task task = new Task("task1", sample);
task.start();

Task task1 = new Task("task2", sample);
task1.start();

try {
 Thread.sleep(5000);
} catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
}

LockSample.thread.interrupt();

4. 결과
- 한놈이 계속 자원을 사용하고 있으면 다른 한놈은 다른 놈이 자원을 사용하고 있다고 울부짓는다. 중간에 인터럽트를 발생시키면 못먹겠다고 울부짖던 놈이 이번엔 지가 처먹는다. 굉장히 단순한넘인디..
task2 : 내가 선점하고 있다.
task1 : 누군가가 선점하고 있다.
task1 : 누군가가 선점하고 있다.
task1 : 누군가가 선점하고 있다.
task1 : 누군가가 선점하고 있다.
task1 : 내가 선점하고 있다.
java.lang.InterruptedException: task2 : 인터럽트 당함
task1 : 내가 선점하고 있다.
task1 : 내가 선점하고 있다.
task1 : 내가 선점하고 있다.
task1 : 내가 선점하고 있다.
task1 : 내가 선점하고 있다.

ps.
초기에는 단순히 여기 저기에 돌아다니는 예제를 참고로 작업을 하다보니 Lock 을 설정만 하고 해제를 제대로 못한 코드가 나온적이 있었다. 예를 들어 여러개의 스레드를 생성해서 테스트를 하다보면 lock을 선점하고 있던 스레드에 인터럽트를 보내서 스레드를 강제 종료 시켜도 다른 스레드에서 해당 lock 이 이미 선점되어 사용할 수 없다는 문제가 발생된다. lock을 설정해서 사용하는것도 중요하지만 해제를 꼭 해줘야 하는 부분이 synchronized 보다 많이 불편하다.

참고
http://blog.sdnkorea.com/blog/178?category=15
java concurrency in practice

Posted by 짱가쟁이