package com.eyu.gift.lock; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.locks.LockSupport; class FailLock { Queue<Thread> queue = new ConcurrentLinkedQueue<Thread>(); public void lock() { queue.add(Thread.currentThread()); if (queue.peek() != Thread.currentThread()) { LockSupport.park(this); } } public void unlock() { queue.remove(); LockSupport.unpark(queue.peek()); } }
测试代码:
package com.eyu.gift.lock; import java.util.concurrent.CountDownLatch; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; public class FailLockTest { public static final int NUM = 5000; public static final int THREAD_NUM = 40; static int[] target = new int[THREAD_NUM]; @Test public void test() throws Exception { final FailLock failLock = new FailLock(); final CountDownLatch endCountDownLatch = new CountDownLatch(THREAD_NUM); final CountDownLatch startCountDownLatch = new CountDownLatch(1); for (int j = 0; j < THREAD_NUM; j++) { final int thread = j; Thread t = new Thread() { @Override public void run() { try { startCountDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 0; i < NUM; i++) { failLock.lock(); ++target[thread]; // System.err.println(target[thread] + " ======== " + Thread.currentThread().getName()); failLock.unlock(); } endCountDownLatch.countDown(); } }; t.setName("线程" + thread); t.start(); } startCountDownLatch.countDown(); endCountDownLatch.await(); int total = 0; for (int i = 0; i < THREAD_NUM; i++) { total += target[i]; } Assert.assertThat(total, Matchers.is(THREAD_NUM * NUM)); } }