為了防止無良網站的爬蟲抓取文章,特此標識,轉載請注明文章出處。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。