ReentrantLock 과 ReentrantReadWriteLock 비교

ReadWriteLock 은 Jdk 5 에서 읽 기와 쓰기 분리 자 물 쇠 를 제공 합 니 다. 읽 기와 쓰기 분리 자 물 쇠 는 자물쇠 경쟁 을 줄 이 고 시스템 성능 을 향상 시 키 는 데 효과 적 입 니 다.재 활용 자물쇠 나 내부 자 물 쇠 를 사용 하면 이론 적 으로 모든 읽 기, 읽 기, 쓰기, 쓰기 사이 가 직렬 작업 이다.그러나 읽 기와 쓰 기 는 여러 스 레 드 를 동시에 읽 을 수 있 고 읽 기와 쓰기 동작 이나 쓰기 동작 은 서로 기다 리 고 자 물 쇠 를 가 져 야 합 니 다.시스템 에서 읽 기 조작 횟수 가 쓰기 조작 횟수 보다 훨씬 많 으 면 읽 기 쓰기 자 물 쇠 는 가장 큰 효 과 를 발휘 하여 시스템 성능 을 향상 시 킬 수 있다.
ReentrantLock
import org.junit.Test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestReadWriteLock {
    private static final int MAX_THREADS = 2000;
    private static final int TASK_COUNT = 4000;
    private static Lock lock = new ReentrantLock();
    java.util.Random rand = new java.util.Random();
    private int value;

    /**
     * ReentrantLock    
     */
    public class ReadWriteThread implements Runnable {
        protected String name;

        public ReadWriteThread() {
        }

        public ReadWriteThread(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try {
                handleRead();
                int v = rand.nextInt(100);
                if (v < 10) {
                    handleWrite(v);
                }
                Thread.sleep(rand.nextInt(100));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *    
     */
    public class CounterPoolExecutor extends ThreadPoolExecutor {
        private AtomicInteger count = new AtomicInteger(0);
        public long startTime = 0;
        public String funcname = "";

        public CounterPoolExecutor(int corePoolSize, int maximumPoolSize,
                                   long keepAliveTime, TimeUnit unit,
                                   BlockingQueue workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        }

        protected void afterExecute(Runnable r, Throwable t) {
            int l = count.addAndGet(1);
            if (l == TASK_COUNT) {
                System.out.println(funcname + " spend time:" + (System.currentTimeMillis() - startTime));

            }
        }
    }

    /**
     * ReentrantLock    
     *
     * @return
     * @throws InterruptedException
     */
    public Object handleRead() throws InterruptedException {
        try {
            lock.lock();
            Thread.sleep(1);
            return value;
        } finally {
            lock.unlock();
        }
    }

    /**
     * ReentrantLock    
     *
     * @param index
     * @throws InterruptedException
     */
    public void handleWrite(int index) throws InterruptedException {
        try {
            lock.lock();
            Thread.sleep(1);
            value = index;
        } finally {
            lock.unlock();
        }
    }

    /**
     *   ReentrantLock
     *
     * @throws InterruptedException
     */
    @Test
    public void testLock() throws InterruptedException {

        CounterPoolExecutor exe = new CounterPoolExecutor(MAX_THREADS, MAX_THREADS,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue());

        long starttime = System.currentTimeMillis();
        exe.startTime = starttime;
        exe.funcname = "testLock";
        for (int i = 0; i < TASK_COUNT; i++)
            exe.submit(new ReadWriteThread());

        Thread.sleep(100000);
    }
}

출력 결과
testLock spend time:6604
 
  
ReentrantReadWriteLock
import org.junit.Test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class TestReadWriteLock {
    private static final int MAX_THREADS = 2000;
    private static final int TASK_COUNT = 4000;
    private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private static Lock readLock = readWriteLock.readLock();
    private static Lock writeLock = readWriteLock.writeLock();

    java.util.Random rand = new java.util.Random();
    private int value;

    /**
     * ReentrantReadWriteLock    
     */
    public class ReadWriteThread2 implements Runnable {
        protected String name;

        public ReadWriteThread2() {
        }

        public ReadWriteThread2(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try {
                handleRead2();
                int v = rand.nextInt(100);
                if (v < 10) {
                    handleWrite2(v);
                }
                Thread.sleep(rand.nextInt(100));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *    
     */
    public class CounterPoolExecutor extends ThreadPoolExecutor {
        private AtomicInteger count = new AtomicInteger(0);
        public long startTime = 0;
        public String funcname = "";

        public CounterPoolExecutor(int corePoolSize, int maximumPoolSize,
                                   long keepAliveTime, TimeUnit unit,
                                   BlockingQueue workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        }

        protected void afterExecute(Runnable r, Throwable t) {
            int l = count.addAndGet(1);
            if (l == TASK_COUNT) {
                System.out.println(funcname + " spend time:" + (System.currentTimeMillis() - startTime));

            }
        }
    }


    /**
     * ReentrantReadWriteLock
     *
     * @return
     * @throws InterruptedException
     */
    public Object handleRead2() throws InterruptedException {
        try {
            readLock.lock();
            Thread.sleep(1);
            return value;
        } finally {
            readLock.unlock();
        }
    }

    /**
     * ReentrantReadWriteLock
     *
     * @param index
     * @throws InterruptedException
     */
    public void handleWrite2(int index) throws InterruptedException {
        try {
            writeLock.lock();
            Thread.sleep(1);
            value = index;
        } finally {
            writeLock.unlock();
        }
    }

    /**
     *      ReentrantReadWriteLock
     *
     * @throws InterruptedException
     */
    @Test
    public void testLock2() throws InterruptedException {
        CounterPoolExecutor executor = new CounterPoolExecutor(MAX_THREADS, MAX_THREADS,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue());

        long starttime = System.currentTimeMillis();
        executor.startTime = starttime;
        executor.funcname = "testLock2";
        for (int i = 0; i < TASK_COUNT; i++) {
            executor.submit(new ReadWriteThread2());
        }
        Thread.sleep(100000);
    }
}

출력 결과
testLock2 spend time:1102

좋은 웹페이지 즐겨찾기