并发编程--并发编程包LockSupport

来源:互联网 发布:pcb layout软件 编辑:程序博客网 时间:2024/06/12 08:05

LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。LockSupport主要提供了两个功能:

(1)park()方法,用来阻塞线程。

(2)unpark()方法,解除阻塞线程。

LockSupport提供的park()和unpark()方法不会遇到Thread.suspend和Thread.resume所可能引起的死锁问题,因为park和unpark有许可的存在,调用park的线程和另一个试图将其unpark()的线程之间的竞争将保持活性。

LockSupport的实现基础是通过sun.misc.Unsafe(真是一个功能强大的类),通过Unsafe提供的park()和unpark()方法来完成线程的阻塞和解除阻塞。

park()阻塞线程:

public static void park(Object blocker) {        Thread t = Thread.currentThread();        setBlocker(t, blocker);        UNSAFE.park(false, 0L);        setBlocker(t, null);    }
private static void setBlocker(Thread t, Object arg) {        // Even though volatile, hotspot doesn't need a write barrier here.        UNSAFE.putObject(t, parkBlockerOffset, arg);    }
完成线程的阻塞,此时线程处于阻塞状态。

unpark()解除线程阻塞:

public static void unpark(Thread thread) {        if (thread != null)            UNSAFE.unpark(thread);    }
完成线程thread的阻塞,这样线程处于可执行状态。

简单示例:子线程运行完之后主线程才运行结束

public class LockSupportLean {private static Thread mainThread;public static void main(String[] args) {mainThread = Thread.currentThread();ThreadA threadA = new ThreadA("a");System.err.println("阻塞主线程");threadA.start();LockSupport.park(mainThread);}static class ThreadA extends Thread{public ThreadA(String name){super(name);}@Overridepublic void run(){System.err.println("运行子线程");LockSupport.unpark(mainThread);}}}

LockSupport源码(jdk8)

public class LockSupport {    private LockSupport() {} // Cannot be instantiated.    private static void setBlocker(Thread t, Object arg) {        // Even though volatile, hotspot doesn't need a write barrier here.        UNSAFE.putObject(t, parkBlockerOffset, arg);    }        public static void unpark(Thread thread) {        if (thread != null)            UNSAFE.unpark(thread);    }    public static void park(Object blocker) {        Thread t = Thread.currentThread();        setBlocker(t, blocker);        UNSAFE.park(false, 0L);        setBlocker(t, null);    }    public static void parkNanos(Object blocker, long nanos) {        if (nanos > 0) {            Thread t = Thread.currentThread();            setBlocker(t, blocker);            UNSAFE.park(false, nanos);            setBlocker(t, null);        }    }    public static void parkUntil(Object blocker, long deadline) {        Thread t = Thread.currentThread();        setBlocker(t, blocker);        UNSAFE.park(true, deadline);        setBlocker(t, null);    }    public static Object getBlocker(Thread t) {        if (t == null)            throw new NullPointerException();        return UNSAFE.getObjectVolatile(t, parkBlockerOffset);    }    public static void park() {        UNSAFE.park(false, 0L);    }       public static void parkNanos(long nanos) {        if (nanos > 0)            UNSAFE.park(false, nanos);    }       public static void parkUntil(long deadline) {        UNSAFE.park(true, deadline);    }    static final int nextSecondarySeed() {        int r;        Thread t = Thread.currentThread();        if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {            r ^= r << 13;   // xorshift            r ^= r >>> 17;            r ^= r << 5;        }        else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)            r = 1; // avoid zero        UNSAFE.putInt(t, SECONDARY, r);        return r;    }       private static final sun.misc.Unsafe UNSAFE;    private static final long parkBlockerOffset;    private static final long SEED;    private static final long PROBE;    private static final long SECONDARY;    static {        try {            UNSAFE = sun.misc.Unsafe.getUnsafe();            Class<?> tk = Thread.class;            parkBlockerOffset = UNSAFE.objectFieldOffset                (tk.getDeclaredField("parkBlocker"));            SEED = UNSAFE.objectFieldOffset                (tk.getDeclaredField("threadLocalRandomSeed"));            PROBE = UNSAFE.objectFieldOffset                (tk.getDeclaredField("threadLocalRandomProbe"));            SECONDARY = UNSAFE.objectFieldOffset                (tk.getDeclaredField("threadLocalRandomSecondarySeed"));        } catch (Exception ex) { throw new Error(ex); }    }}





0 0
原创粉丝点击