转载 http://my.oschina.net/digerl/blog/33282
为了比较一下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的源码
view plaincopy to clipboardprint?
01.public abstract class Test {   
02.    protected String id;   
03.    protected CyclicBarrier barrier;   
04.    protected long count;   
05.    protected int 
threadNum;   
06.    protected Executor
Service executor;   
07.  
08.    public Test(String id, CyclicBarrier barrier, long count, int threadNum,   
09.            ExecutorService executor) {   
10.        this.id = id;   
11.        this.barrier = barrier;   
12.        this.count = count;   
13.        this.threadNum = threadNum;   
14.        this.executor = executor;   
15.    }   
16.  
17.    public void startTest() {   
18.  
19.        long start = System.currentTimeMillis();   
20.  
21.        for (int j = 0; j < threadNum; j++) {   
22.            executor.execute(new Thread() {   
23.                @Override  
24.                public void run() {   
25.                    for (int i = 0; i < count; i++) {   
26.                        test();   
27.                    }   
28.  
29.                    try {   
30.                        barrier.await();   
31.  
32.                    } catch (InterruptedException e) {   
33.                        e.printStackTrace();   
34.                    } catch (BrokenBarrierException e) {   
35.                        e.printStackTrace();   
36.                    }   
37.                }   
38.            });   
39.        }   
40.  
41.        try {   
42.            barrier.await();   
43.        } catch (InterruptedException e) {   
44.            e.printStackTrace();   
45.        } catch (BrokenBarrierException e) {   
46.            e.printStackTrace();   
47.        }   
48.  
49.        // 所有线程执行完成之后,才会跑到这一步   
50.        long duration = System.currentTimeMillis() - start;   
51.        System.out.println(id + " = " + duration);   
52.    }   
53.  
54.    protected abstract void test();   
55.}  
public abstract class Test {
 protected String id;
 protected CyclicBarrier barrier;
 protected long count;
 protected int threadNum;
 protected ExecutorService executor;
 public Test(String id, CyclicBarrier barrier, long count, int threadNum,
   ExecutorService executor) {
  this.id = id;
  this.barrier = barrier;
  this.count = count;
  this.threadNum = threadNum;
  this.executor = executor;
 }
 public void startTest() {
  long start = System.currentTimeMillis();
  for (int j = 0; j < threadNum; j++) {
   executor.execute(new Thread() {
    @Override
    public void run() {
     for (int i = 0; i < count; i++) {
      test();
     }
     try {
      barrier.await();
     } catch (InterruptedException e) {
      e.printStackTrace();
     } catch (BrokenBarrierException e) {
      e.printStackTrace();
     }
    }
   });
  }
  try {
   barrier.await();
  } catch (InterruptedException e) {
   e.printStackTrace();
  } catch (BrokenBarrierException e) {
   e.printStackTrace();
  }
  // 所有线程执行完成之后,才会跑到这一步
  long duration = System.currentTimeMillis() - start;
  System.out.println(id + " = " + duration);
 }
 protected abstract void test();
}
 
测试类ReentreLockTest 源码
 
view plaincopy to clipboardprint?
01.import thread.test.Test;   
02.  
03.public class ReentreLockTest {   
04.    private static long COUNT = 1000000;   
05.    private static Lock lock = new ReentrantLock();   
06.    private static long lockCounter = 0;   
07.    private static long syncCounter = 0;   
08.    private static long semaCounter = 0;   
09.    private static AtomicLong atomicCounter = new AtomicLong(0);   
10.    private static Object syncLock = new Object();   
11.    private static Semaphore mutex = new Semaphore(1);   
12.  
13.    public static void testLock(int num, int threadCount) {   
14.  
15.    }   
16.  
17.    static long getLock() {   
18.        lock.lock();   
19.        try {   
20.            return lockCounter;   
21.        } finally {   
22.            lock.unlock();   
23.        }   
24.    }   
25.  
26.    static long getSync() {   
27.        synchronized (syncLock) {   
28.            return syncCounter;   
29.        }   
30.    }   
31.  
32.    static long getAtom() {   
33.        return atomicCounter.get();   
34.    }   
35.  
36.    static long getSemaphore() throws InterruptedException {   
37.        mutex.acquire();   
38.  
39.        try {   
40.            return semaCounter;   
41.        } finally {   
42.            mutex.release();   
43.        }   
44.    }   
45.  
46.    static long getLockInc() {   
47.        lock.lock();   
48.        try {   
49.            return ++lockCounter;   
50.        } finally {   
51.            lock.unlock();   
52.        }   
53.    }   
54.  
55.    static long getSyncInc() {   
56.        synchronized (syncLock) {   
57.            return ++syncCounter;   
58.        }   
59.    }   
60.  
61.    static long getAtomInc() {   
62.        return atomicCounter.getAndIncrement();   
63.    }   
64.  
65.    static class SemaTest extends Test {   
66.  
67.        public SemaTest(String id, CyclicBarrier barrier, long count,   
68.                int threadNum, ExecutorService executor) {   
69.            super(id, barrier, count, threadNum, executor);   
70.        }   
71.  
72.        @Override  
73.        protected void test() {   
74.            try {   
75.                getSemaphore();   
76.            } catch (InterruptedException e) {   
77.                e.printStackTrace();   
78.            }   
79.        }   
80.  
81.    }   
82.  
83.    static class LockTest extends Test {   
84.  
85.        public LockTest(String id, CyclicBarrier barrier, long count,   
86.                int threadNum, ExecutorService executor) {   
87.            super(id, barrier, count, threadNum, executor);   
88.        }   
89.  
90.        @Override  
91.        protected void test() {   
92.            getLock();   
93.        }   
94.  
95.    }   
96.  
97.    static class SyncTest extends Test {   
98.  
99.        public SyncTest(String id, CyclicBarrier barrier, long count,   
100.                int threadNum, ExecutorService executor) {   
101.            super(id, barrier, count, threadNum, executor);   
102.        }   
103.  
104.        @Override  
105.        protected void test() {   
106.            getSync();   
107.        }   
108.  
109.    }   
110.  
111.    static class AtomicTest extends Test {   
112.  
113.        public AtomicTest(String id, CyclicBarrier barrier, long count,   
114.                int threadNum, ExecutorService executor) {   
115.            super(id, barrier, count, threadNum, executor);   
116.        }   
117.  
118.        @Override  
119.        protected void test() {   
120.            getAtom();   
121.        }   
122.  
123.    }   
124.  
125.    public static void test(String id, long count, int threadNum,   
126.            ExecutorService executor) {   
127.  
128.        final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,   
129.                new Thread() {   
130.  
131.                    @Override  
132.                    public void run() {   
133.  
134.                    }   
135.                });   
136.  
137.        System.out.println("==============================");   
138.        System.out.println("count = " + count + "\t" + "Thread Count = "  
139.                + threadNum);   
140.  
141.        new LockTest("Lock ", barrier, COUNT, threadNum, executor).startTest();   
142.        new SyncTest("Sync ", barrier, COUNT, threadNum, executor).startTest();   
143.        new AtomicTest("Atom ", barrier, COUNT, threadNum, executor)   
144.                .startTest();   
145.        new SemaTest("Sema ", barrier, COUNT, threadNum, executor)   
146.                .startTest();   
147.        System.out.println("==============================");   
148.    }   
149.  
150.    public static void main(String[] args) {   
151.        for (int i = 1; i < 5; i++) {   
152.            ExecutorService executor = Executors.newFixedThreadPool(10 * i);   
153.            test("", COUNT * i, 10 * i, executor);   
154.        }   
155.    }   
156.}  
import thread.test.Test;
public class ReentreLockTest {
 private static long COUNT = 1000000;
 private static Lock lock = new ReentrantLock();
 private static long lockCounter = 0;
 private static long syncCounter = 0;
 private static long semaCounter = 0;
 private static AtomicLong atomicCounter = new AtomicLong(0);
 private static Object syncLock = new Object();
 private static Semaphore mutex = new Semaphore(1);
 public static void testLock(int num, int threadCount) {
 }
 static long getLock() {
  lock.lock();
  try {
   return lockCounter;
  } finally {
   lock.unlock();
  }
 }
 static long getSync() {
  synchronized (syncLock) {
   return syncCounter;
  }
 }
 static long getAtom() {
  return atomicCounter.get();
 }
 static long getSemaphore() throws InterruptedException {
  mutex.acquire();
  try {
   return semaCounter;
  } finally {
   mutex.release();
  }
 }
 static long getLockInc() {
  lock.lock();
  try {
   return ++lockCounter;
  } finally {
   lock.unlock();
  }
 }
 static long getSyncInc() {
  synchronized (syncLock) {
   return ++syncCounter;
  }
 }
 static long getAtomInc() {
  return atomicCounter.getAndIncrement();
 }
 static class SemaTest extends Test {
  public SemaTest(String id, CyclicBarrier barrier, long count,
    int threadNum, ExecutorService executor) {
   super(id, barrier, count, threadNum, executor);
  }
  @Override
  protected void test() {
   try {
    getSemaphore();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
 static class LockTest extends Test {
  public LockTest(String id, CyclicBarrier barrier, long count,
    int threadNum, ExecutorService executor) {
   super(id, barrier, count, threadNum, executor);
  }
  @Override
  protected void test() {
   getLock();
  }
 }
 static class SyncTest extends Test {
  public SyncTest(String id, CyclicBarrier barrier, long count,
    int threadNum, ExecutorService executor) {
   super(id, barrier, count, threadNum, executor);
  }
  @Override
  protected void test() {
   getSync();
  }
 }
 static class AtomicTest extends Test {
  public AtomicTest(String id, CyclicBarrier barrier, long count,
    int threadNum, ExecutorService executor) {
   super(id, barrier, count, threadNum, executor);
  }
  @Override
  protected void test() {
   getAtom();
  }
 }
 public static void test(String id, long count, int threadNum,
   ExecutorService executor) {
  final CyclicBarrier barrier = new CyclicBarrier(threadNum + 1,
    new Thread() {
     @Override
     public void run() {
     }
    });
  System.out.println("==============================");
  System.out.println("count = " + count + "\t" + "Thread Count = "
    + threadNum);
  new LockTest("Lock ", barrier, COUNT, threadNum, executor).startTest();
  new SyncTest("Sync ", barrier, COUNT, threadNum, executor).startTest();
  new AtomicTest("Atom ", barrier, COUNT, threadNum, executor)
    .startTest();
  new SemaTest("Sema ", barrier, COUNT, threadNum, executor)
    .startTest();
  System.out.println("==============================");
 }
 public static void main(String[] args) {
  for (int i = 1; i < 5; i++) {
   ExecutorService executor = Executors.newFixedThreadPool(10 * i);
   test("", COUNT * i, 10 * i, executor);
  }
 }
}
 
结果
view plaincopy to clipboardprint?
01.==============================   
02.count = 1000000 Thread Count = 10   
03.Lock  = 953   
04.Sync  = 3781   
05.Atom  = 78   
06.Sema  = 4922   
07.==============================   
08.==============================   
09.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.==============================