为了比较一下ReentrantLock和synchronized的性能,做了一下性能测试:

得出结论:

(1)使用Lock的性能比使用synchronized关键字要提高4~5倍;

(2)使用信号量实现同步的速度大约比synchronized要慢10~20%;

(3)使用atomic包的AtomicInter速度是比Lock要快1一个数量级。

 

ReentrantLock 类
java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为 Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。ReentrantLock 类实现了 Lock,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上。)

reentrant 锁意味着什么呢?简单来说,它有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1,然后锁需要被释放两次才能获得真正释放。这模仿了 synchronized 的语义;如果线程进入由线程已经拥有的监控器保护的 synchronized 块,就允许线程继续进行,当线程退出第二个(或者后续)synchronized 块的时候,不释放锁,只有线程退出它进入的监控器保护的第一个 synchronized 块时,才释放锁。

在查看清单 1 中的代码示例时,可以看到 Lock 和 synchronized 有一点明显的区别 —— lock 必须在 finally 块中释放。否则,如果受保护的代码将抛出异常,锁就有可能永远得不到释放!这一点区别看起来可能没什么,但是实际上,它极为重要。忘记在 finally 块中释放锁,可能会在程序中留下一个定时bomb,当有一天bomb爆炸时,您要花费很大力气才有找到源头在哪。而使用同步,JVM 将确保锁会获得自动释放。

 

Test的源码

  1. public abstract class Test {
  2.     protected String id;
  3.     protected CyclicBarrier barrier;
  4.     protected long count;
  5.     protected int threadNum;
  6.     protected ExecutorService executor;
  7.     public Test(String id, CyclicBarrier barrier, long count, int threadNum,
  8.             ExecutorService executor) {
  9.         this.id = id;
  10.         this.barrier = barrier;
  11.         this.count = count;
  12.         this.threadNum = threadNum;
  13.         this.executor = executor;
  14.     }
  15.     public void startTest() {
  16.         long start = System.currentTimeMillis();
  17.         for (int j = 0; j < threadNum; j++) {
  18.             executor.execute(new Thread() {
  19.                 @Override
  20.                 public void run() {
  21.                     for (int i = 0; i < count; i++) {
  22.                         test();
  23.                     }
  24.                     try {
  25.                         barrier.await();
  26.                     } catch (InterruptedException e) {
  27.                         e.printStackTrace();
  28.                     } catch (BrokenBarrierException e) {
  29.                         e.printStackTrace();
  30.                     }
  31.                 }
  32.             });
  33.         }
  34.         try {
  35.             barrier.await();
  36.         } catch (InterruptedException e) {
  37.             e.printStackTrace();
  38.         } catch (BrokenBarrierException e) {
  39.             e.printStackTrace();
  40.         }
  41.         // 所有线程执行完成之后,才会跑到这一步
  42.         long duration = System.currentTimeMillis() – start;
  43.         System.out.println(id + ” = ” + duration);
  44.     }
  45.     protected abstract void test();
  46. }

 

 

测试类ReentreLockTest 源码

 

  1. import thread.test.Test;
  2. public class ReentreLockTest {
  3.     private static long COUNT = 1000000;
  4.     private static Lock lock = new ReentrantLock();
  5.     private static long lockCounter = 0;
  6.     private static long syncCounter = 0;
  7.     private static long semaCounter = 0;
  8.     private static AtomicLong atomicCounter = new AtomicLong(0);
  9.     private static Object syncLock = new Object();
  10.     private static Semaphore mutex = new Semaphore(1);
  11.     public static void testLock(int num, int threadCount) {
  12.     }
  13.     static long getLock() {
  14.         lock.lock();
  15.         try {
  16.             return lockCounter;
  17.         } finally {
  18.             lock.unlock();
  19.         }
  20.     }
  21.     static long getSync() {
  22.         synchronized (syncLock) {
  23.             return syncCounter;
  24.         }
  25.     }
  26.     static long getAtom() {
  27.         return atomicCounter.get();
  28.     }
  29.     static long getSemaphore() throws InterruptedException {
  30.         mutex.acquire();
  31.         try {
  32.             return semaCounter;
  33.         } finally {
  34.             mutex.release();
  35.         }
  36.     }
  37.     static long getLockInc() {
  38.         lock.lock();
  39.         try {
  40.             return ++lockCounter;
  41.         } finally {
  42.             lock.unlock();
  43.         }
  44.     }
  45.     static long getSyncInc() {
  46.         synchronized (syncLock) {
  47.             return ++syncCounter;
  48.         }
  49.     }
  50.     static long getAtomInc() {
  51.         return atomicCounter.getAndIncrement();
  52.     }
  53.     static class SemaTest extends Test {
  54.         public SemaTest(String id, CyclicBarrier barrier, long count,
  55.                 int threadNum, ExecutorService executor) {
  56.             super(id, barrier, count, threadNum, executor);
  57.         }
  58.         @Override
  59.         protected void test() {
  60.             try {
  61.                 getSemaphore();
  62.             } catch (InterruptedException e) {
  63.                 e.printStackTrace();
  64.             }
  65.         }
  66.     }
  67.     static class LockTest extends Test {
  68.         public LockTest(String id, CyclicBarrier barrier, long count,
  69.                 int threadNum, ExecutorService executor) {
  70.             super(id, barrier, count, threadNum, executor);
  71.         }
  72.         @Override
  73.         protected void test() {
  74.             getLock();
  75.         }
  76.     }
  77.     static class SyncTest extends Test {
  78.         public SyncTest(String id, CyclicBarrier barrier, long count,
  79.                 int threadNum, ExecutorService executor) {
  80.             super(id, barrier, count, threadNum, executor);
  81.         }
  82.         @Override
  83.         protected void test() {
  84.             getSync();
  85.         }
  86.     }
  87.     static class AtomicTest extends Test {
  88.         public AtomicTest(String id, CyclicBarrier barrier, long count,
  89.                 int threadNum, ExecutorService executor) {
  90.             super(id, barrier, count, threadNum, executor);
  91.         }
  92.         @Override
  93.         protected void test() {
  94.             getAtom();
  95.         }
  96.     }
  97.     public static void test(String id, long count, int threadNum,
  98.             ExecutorService executor) {
  99.         final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,
  100.                 new Thread() {
  101.                     @Override
  102.                     public void run() {
  103.                     }
  104.                 });
  105.         System.out.println(“==============================”);
  106.         System.out.println(“count = ” + count + “/t” + “Thread Count = “
  107.                 + threadNum);
  108.         new LockTest(“Lock “, barrier, COUNT, threadNum, executor).startTest();
  109.         new SyncTest(“Sync “, barrier, COUNT, threadNum, executor).startTest();
  110.         new AtomicTest(“Atom “, barrier, COUNT, threadNum, executor)
  111.                 .startTest();
  112.         new SemaTest(“Sema “, barrier, COUNT, threadNum, executor)
  113.                 .startTest();
  114.         System.out.println(“==============================”);
  115.     }
  116.     public static void main(String[] args) {
  117.         for (int i = 1; i < 5; i++) {
  118.             ExecutorService executor = Executors.newFixedThreadPool(10 * i);
  119.             test(“”, COUNT * i, 10 * i, executor);
  120.         }
  121.     }
  122. }

 

 

 

 

结果

 

 

[c-sharp] view plaincopy
  1. ==============================
  2. count = 1000000 Thread Count = 10
  3. Lock  = 953
  4. Sync  = 3781
  5. Atom  = 78
  6. Sema  = 4922
  7. ==============================
  8. ==============================
  9. count = 2000000 Thread Count = 20
  10. Lock  = 1906
  11. Sync  = 8469
  12. Atom  = 172
  13. Sema  = 9719
  14. ==============================
  15. ==============================
  16. count = 3000000 Thread Count = 30
  17. Lock  = 2890
  18. Sync  = 12641
  19. Atom  = 219
  20. Sema  = 15015
  21. ==============================
  22. ==============================
  23. count = 4000000 Thread Count = 40
  24. Lock  = 3844
  25. Sync  = 17141
  26. Atom  = 343
  27. Sema  = 19782
  28. ==============================

http://blog.csdn.net/arkblue/article/details/6138598

参考http://zzhonghe.javaeye.com/blog/826162

 

 сервисы раскрутки сайталучший отдых в маевзять денег в долг в калугепутевки на шри ланку в августе 2015japanese to englishпроверить позицию сайта по запросууправление репутацией в сети интернетпокупка ссылок яндексрадиаторы на заказдома стройка

引用地址:http://www.hikin.net/?p=1190

  留言暂时关闭