LockSupport

LockSupport简介
LockSupport用来实现线程的挂起和唤醒,它是Java6引入的一个工具类,它简单灵活,应用广泛,同时也是构建同步组件的基础工具。

LockSupport API

// 阻塞当前线程,调用unpark(Thread thread)方法或者当前线程被中断,才能从park返回
void park()
// 阻塞当前线程但时间不超过nanos纳秒
void parkNanos(long nanos)
// 阻塞当前线程直到deadline时间(从1970开始到deadline时间毫秒数)
void parkUntil(long deadline)
// 唤醒处于阻塞状态的线程
void unpark(Thread thread)

// java6增加了以下3个方法
void park(Object blocker)

void parkNanos(Object blocker,long nanos)

void parkUntil(Object blocker,long deadline)

用于实现阻塞当前线程的功能,blocker用于标识当前线程正在等待的对象(阻塞对象),该对象主要用于给开发人员提供阻塞对象的信息,有助于问题排查和系统监控。

Object等待唤醒wait/notify/notifyAll

// object wait notify
public static void main(String[] args) throws InterruptedException {
        final Object obj = new Object();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    synchronized (obj){
                        obj.wait();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
                System.out.println("go here");
            }
        });
        thread.start();
        Thread.sleep(1000);
        synchronized (obj){
            obj.notify();
        }
    }

// 上述睡眠一秒钟,保证线程thread阻塞在wait方法,若此处注释,主线程先notify,
// 可能程序一直处于wait等待状态,所以必须先阻塞后notify。
// 可见Object的wait与notify的调用是有先后顺序的。

 LockSupport阻塞唤醒park/unpark

public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    LockSupport.park();
                }catch (Exception e){
                    e.printStackTrace();
                }
                System.out.println("go here");
            }
        });
        thread.start();
        LockSupport.unpark(thread);
    }

// LockSupport支持主线程先调用unpark后,线程thread再调用park而不被阻塞。

总结一下,LockSupport与Object(wait/notify)不同点:
①LockSupport不需要在同步代码块里 ,所以线程间也不需要维护一个共享的同步对象,实现了线程间的解耦。
​②unpark函数可以先于park调用,所以不需要担心线程间的执行的先后顺序。
③多次调用unpark方法和调用一次unpark方法效果一样,比如线程A连续调用两次LockSupport.unpark(B)方法唤醒线程B,然后线程B调用两次LockSupport.park()方法, 线程B依旧会被阻塞。因为两次unpark调用效果跟一次调用一样,只能让线程B的第一次调用park方法不被阻塞,第二次调用依旧会阻塞。
 

你可能感兴趣的:(并发编程)