1.使用Unsafe类
import sun.misc.Unsafe; class UnsafePackage { private static Unsafe unsafe; static { try { Class<Unsafe> unsafeClass = Unsafe.class; Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); unsafe = (Unsafe) theUnsafe.get(null); } catch (Exception ex) { ex.printStackTrace(); } } public static Unsafe getUnsafe() { return unsafe; } }
2.声明简单锁
class CustomLock { private volatile int status; private static Unsafe unsafe = UnsafePackage.getUnsafe(); private static long statusOffset; private WaitingQueue queue = new WaitingQueue(); static { try { statusOffset = unsafe.objectFieldOffset(CustomLock.class.getDeclaredField("status")); } catch (Exception ex) { ex.printStackTrace(); } } private boolean comareAndSetStatus(int originalStatus, int updateStatus) { return unsafe.compareAndSwapInt(this, statusOffset, originalStatus, updateStatus); } public boolean lock() { if (comareAndSetStatus(0, 1)) { //System.out.println("竞争锁成功!继续执行后面的代码"); return true; } //System.out.println("竞争锁失败!进入等待队列"); push(Thread.currentThread()); while (!comareAndSetStatus(0, 1)) { UnsafePackage.getUnsafe().park(false, 0); } return true; } public boolean unlock() { status = 0; Thread thread = pop(); if (thread != null) { UnsafePackage.getUnsafe().unpark(thread); } return true; } private void push(Thread thread) { queue.push(thread); } private Thread pop() { return queue.pop(); } }
3.竞争锁失败的进队列
class WaitingQueue { private volatile int status; private static long statusOffset; /** * 非线程安全,使用时,也要加锁 */ private LinkedList<Thread> queue = new LinkedList<>(); static { try { statusOffset = UnsafePackage.getUnsafe().objectFieldOffset(WaitingQueue.class.getDeclaredField("status")); } catch (Exception ex) { ex.printStackTrace(); } } public void push(Thread thread) { while (!comareAndSetStatus(0, 1)) { } queue.offerLast(thread); comareAndSetStatus(1, 0); return; } public Thread pop() { while (!comareAndSetStatus(0, 1)) { } Thread elem = null; if (!queue.isEmpty()) { elem = queue.pop(); } comareAndSetStatus(1, 0); return elem; } private boolean comareAndSetStatus(int originalStatus, int updateStatus) { return UnsafePackage.getUnsafe().compareAndSwapInt(this, statusOffset, originalStatus, updateStatus); } }
3.调用如下
public class CustomLockTest { private static int count = 0; public static void main(String[] args) throws InterruptedException { int threadCount = 1500; CountDownLatch countDownLatch = new CountDownLatch(threadCount); CustomLock lock = new CustomLock(); long start = System.currentTimeMillis(); IntStream.range(0, threadCount) .forEach(p -> { new Thread() { @Override public void run() { lock.lock(); try { for (int i = 0; i < 1000; i++) { count++; } countDownLatch.countDown(); } finally { lock.unlock(); } } }.start(); }); countDownLatch.await(); long end = System.currentTimeMillis(); System.out.println("结果值为:" + count + ",共花费了" + (end - start) + "毫秒!"); } }
结果值为:1500000,共花费了601毫秒!