用Java原子变量的CAS方法实现一个自旋锁
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。
http://www.cnblogs.com/shijiaqi1066/p/5999610.html
实现:
package sjq.mylock; import java.util.concurrent.atomic.AtomicReference; public class SpinLock { private AtomicReference<Thread> owner = new AtomicReference<>(); public void lock(){ Thread currentThread = Thread.currentThread(); while(!owner.compareAndSet(null, currentThread)){ // owner == null ,则compareAndSet返回true,否则为false。 //拿不到owner的线程,不断的在死循环 } } public void unLock(){ owner.set(null); // 也可以这样写,太麻烦,没必要 /* Thread cur = Thread.currentThread(); owner.compareAndSet(cur, null); */ } }
测试:
package sjq.mylock; import java.util.concurrent.CountDownLatch; import org.junit.Test; public class TestSpinLock { final static int THREAD_NUM = 100; static int x = 0; @Test public void testLock() throws InterruptedException { CountDownLatch latch = new CountDownLatch(THREAD_NUM); // 锁 SpinLock spinLock = new SpinLock(); for (int i = 0; i < THREAD_NUM; i++) { // 启动子线程 new Thread(() -> { // 每个线程循环多次,频繁上锁,解锁。 for (int n = 0; n < 100; n++) { spinLock.lock(); x++; spinLock.unLock(); } latch.countDown(); // 子线程通知主线程,工作完毕。 }).start(); } latch.await(); // 主线程等待所有子线程结束。 System.out.println(x); // 最终打印结果:10000 ,未出现线程不安全的异常。 } }
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。