天天看點

JUC之LockSupport-多線程與高并發

LockSupport的意思就是有兩個方法park()和unpark(thread)控制線程的阻塞和喚醒。park()是說目前線程執行該方法後進入阻塞狀态,需要再調用unpark(thread)解除阻塞限制。如果unpark(thread)先于park()執行,則該次park()不起作用不會使得線程阻塞。

我們可以使用它來阻塞和喚醒線程,功能和wait,notify有些相似,但是LockSupport比起wait,notify功能更強大。

  • wait和notify都是Object中的方法,在調用這兩個方法前必須先獲得鎖對象,這限制了其使用場合:隻能在同步代碼塊中。
  • 當對象的等待隊列中有多個線程時,notify隻能随機選擇一個線程喚醒,無法喚醒指定的線程。
package basic.aqs.LockSupport;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

public class TestLockSupport {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            for (int i = 0; i < 10; i++) {
                System.out.println(i);
                if (i==5)
                    LockSupport.park();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });

        t.start();
        try {
            TimeUnit.SECONDS.sleep(8);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("8s sleep done");
        LockSupport.unpark(t);

    }
}
           
package basic.aqs.LockSupport;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;

/**
 * 官方給的LockSupport示例
 * 實作的是一個先進先出的線程等待隊列
 * 使用park和unpark控制線程的阻塞和喚醒
 */
class FIFOMutex {
    private final AtomicBoolean locked = new AtomicBoolean(false);
    private final Queue<Thread> waiters
            = new ConcurrentLinkedQueue<>();

    public void lock() {
        boolean wasInterrupted = false;
        // publish current thread for unparkers
        waiters.add(Thread.currentThread());

        // Block while not first in queue or cannot acquire lock
        while (waiters.peek() != Thread.currentThread() ||
                !locked.compareAndSet(false, true)) {
            LockSupport.park(this);
            // ignore interrupts while waiting
            if (Thread.interrupted())
                wasInterrupted = true;
        }

        waiters.remove();
        // ensure correct interrupt status on return
        if (wasInterrupted)
            Thread.currentThread().interrupt();
    }

    public void unlock() {
        locked.set(false);
        LockSupport.unpark(waiters.peek());
    }

    static {
        // Reduce the risk of "lost unpark" due to classloading
        Class<?> ensureLoaded = LockSupport.class;
    }
}
           

https://www.cnblogs.com/takumicx/p/9328459.html