자바 의 높 은 병렬 프로 그래 밍 시리즈(5)reentrentlock 교체 synchronized

자바 고 병발 프로 그래 밍 은 주로 다음 과 같은 세 가지 구성 이 있 습 니 다.1.동기 화기 synchronized 2.동기 용기 3.스 레 드 탱크:threadPool,executort
이 예 에서 test 1 이 this 를 잠 그 기 때문에 test 1 이 실 행 될 때 만 test 2 가 실 행 될 수 있 습 니 다.
public class ReentrantLock1 {
    public synchronized void test1(){
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public synchronized void test2(){
        System.out.println("execute test2........");
    }
    public static void main(String[] args) {
        ReentrantLock1 rl = new ReentrantLock1();
        new Thread(rl::test1).start();  
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(rl::test2).start();
    }
}

reentrentlock 을 사용 하면 같은 기능 을 수행 할 수 있 습 니 다.주의해 야 할 것 은 수 동 으로 자 물 쇠 를 풀 어야 한 다 는 것 입 니 다(중요 한 것 은 세 번 말 합 니 다).syn 잠 금 을 사용 하면 이상 이 발생 하면 jvm 은 자동 으로 잠 금 을 풀 지만 lock 은 수 동 으로 잠 금 을 풀 어야 하기 때문에 finally 에서 자주 잠 금 을 풀 수 있 습 니 다.
public class ReentrantLock2 {
    Lock lock = new ReentrantLock();
    public void test1(){
        try {
            lock.lock(); //synchronized(this)
            for (int i = 0; i < 10; i++) {
            System.out.println(i);

            TimeUnit.SECONDS.sleep(1);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally { //      
            lock.unlock(); 
        }
    }
    public void test2(){
        lock.lock();
        System.out.println("execute test2........");
        lock.unlock();
    }
    public static void main(String[] args) {
        ReentrantLock2 rl = new ReentrantLock2();
        new Thread(rl::test1).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(rl::test2).start();
    }
}

reentrentlock 을 사용 하면'잠 금 시도'tryLock 을 진행 할 수 있 습 니 다.잠 금 이 되 지 않 거나 지 정 된 시간 내 에 잠 금 이 되 지 않 습 니 다.스 레 드 는 계속 기다 릴 지 여 부 를 결정 할 수 있 습 니 다.
public class ReentrantLock3 {
    Lock lock = new ReentrantLock();
    public void test1(){
        try {
            lock.lock(); //synchronized(this)
            for (int i = 0; i < 10; i++) {
            System.out.println(i);

            TimeUnit.SECONDS.sleep(1);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally { //      
            lock.unlock();
        }
    }
    /**
     *     tryLock      ,      ,        
     *     tryLock           
     *      tryLock   ,  tryLock(time)    ,     unclock   ,    finally 
     */
    public void test2(){
        boolean locked = false;
        try {
            lock.tryLock(6, TimeUnit.SECONDS);
            System.out.println("test2...." + locked);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (locked) {
                lock.unlock();
            }
        }
    }
    public static void main(String[] args) {
        ReentrantLock3 rl = new ReentrantLock3();
        new Thread(rl::test1).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(rl::test2).start();
    }
}

ReentrantLock 을 사용 하면 lockInterruptibly 방법 도 호출 할 수 있 습 니 다.스 레 드 interrupt 방법 에 응답 할 수 있 습 니 다.한 스 레 드 가 자 물 쇠 를 기다 리 는 과정 에서 끊 길 수 있 습 니 다.
public class ReentrantLock4 {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();   
        Thread t1 = new Thread(()->{
            try {
                lock.lock();
                System.out.println("t1 start");
                TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
                System.out.println("t1 end");
            } catch (InterruptedException e) {
                System.out.println("interrupted!");
            } finally {
                lock.unlock();
            } 
        });
        t1.start();
        Thread t2 = new Thread(()->{
            try {
                //lock.lock();
                lock.lockInterruptibly(); //   interrupt()      
                System.out.println("t2 start");
                TimeUnit.SECONDS.sleep(5);
                System.out.println("t2 end");
            } catch (InterruptedException e) {
                System.out.println("interrupted!");
            } finally {
                lock.unlock();
            }
        });
        t2.start(); 
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t2.interrupt(); //    2   
    }
}

ReentrantLock 은 공평자물쇠 로 도 지정 할 수 있 습 니 다.
public class ReentrantLock5 extends Thread{

    private static ReentrantLock lock = new ReentrantLock(true); //   true      ,       

    @Override
    public void run() {
        for (int i = 0; i < 100 ; i++) {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "   ");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
    public static void main(String[] args) {
        ReentrantLock5 rl = new ReentrantLock5();
        Thread t1 = new Thread(rl);
        Thread t2 = new Thread(rl);
        t1.start();
        t2.start();
    }
}

좋은 웹페이지 즐겨찾기