檢測synchronized與ReentrantLock性能差別

在java併發編程實戰中說synchronized與ReentrantLock性能從java1.6之後基本持平,而且網上也有人這樣說,而後我就用程序測試一下,測試環境jdk1.8 ,cpu i5-4210H,代碼以下:java

public class LockPerformanceTest {編程

    static int threadCount = 8;併發

    public static void main(String[] args) throws InterruptedException {
        testReentrantLock();
        
        Thread.sleep(1000);
        testSynchronized();
        
    }oop

    private static void testSynchronized() {
        List<Thread> threads = new ArrayList<>();
        AtomicBoolean breakTag = new AtomicBoolean(false);
        HashSet<String> set = new HashSet<String>();
        final AtomicLong counter = new AtomicLong();
        String val = "1";
        for (int i = 0; i < threadCount; i++) {
            Thread t = new Thread() {
                public void run() {
                    this.setPriority(NORM_PRIORITY);
                    while (!breakTag.get()) {
                        synchronized (set) {
                            set.contains(val);
                        }
                        counter.incrementAndGet();
                    }
                }
            };
            threads.add(t);
            t.start();
            
        }性能

        Thread t=    new Thread() {
            public void run() {
                this.setPriority(NORM_PRIORITY);
                long lastCount = counter.get();
                int loop = 0;
                long total = 0;
                while (true) {
                    long tempCount = counter.get() - lastCount;
                    total += tempCount;測試

                    lastCount = counter.get();
                    loop++;
                    if (loop >= 5) {
                        System.out
                                .println("Synchronized平均處理個數:" + total / loop);
                        breakTag.set(true);
                        break;
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }this

                }
            }
        };
        threads.add(t);
        t.start();
        for(Thread th : threads){
            try {
                th.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }線程

    private static void testReentrantLock() {
        List<Thread> threads = new ArrayList<>();
        AtomicBoolean breakTag = new AtomicBoolean(false);
        HashSet<String> set = new HashSet<String>();
        final AtomicLong counter = new AtomicLong();
        ReentrantLock lock = new ReentrantLock();
        String val = "1";
        for (int i = 0; i < threadCount; i++) {
            Thread t = new Thread() {
                public void run() {
                    this.setPriority(NORM_PRIORITY);
                    while (!breakTag.get()) {
                        lock.lock();
                        try {
                            set.contains(val);
                        } finally {
                            lock.unlock();
                        }
                        counter.incrementAndGet();
                    }
                }
            };
            threads.add(t);
            t.start();
        }orm

        Thread t=    new Thread() {
            public void run() {
                this.setPriority(NORM_PRIORITY);
                long lastCount = counter.get();
                int loop = 0;
                long total = 0;
                while (true) {
                    long tempCount = counter.get() - lastCount;
                    total += tempCount;rem

                    lastCount = counter.get();
                    loop++;
                    if (loop >= 5) {
                        System.out.println("ReentrantLock平均處理個數:" + total
                                / loop);
                        breakTag.set(true);
                        break;
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        };
        threads.add(t);
        t.start();
        for(Thread th : threads){
            try {
                th.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

最後測試結果以下:在線程個數是1個的時候,性能差很少;2個時synchronized > ReentrantLock;2個以上ReentrantLock > synchronized,而且性能差距有0.5倍左右。因此在對性能要求不是很高的狀況下仍是用synchronized,畢竟使用方便,ReentrantLock在對性能有較高要求時使用,而且靈活性高,可是容易編程出錯,萬一忘了在finally中釋放鎖將形成死鎖。

相關文章
相關標籤/搜索