实现两线程的同步二(lockSupport的park/unpark)

1、使用LockSupport的part/unpark实现

package com.ares.thread;

import java.util.concurrent.locks.LockSupport;

public class WaitAndNotifyDemo {
    
    public static void main(String[] args) {
        MThread myThread = new MThread(Thread.currentThread());
        myThread.start();
        System.out.println("before park");
        // 获取许可 表示当前线程将会等待,直至获得许可
        LockSupport.park("ParkAndUnparkDemo");
        System.out.println("after park");
    }
}

class MThread extends Thread {
    private Object object;
    public MThread(Object object) {
        this.object = object;
    }

    public void run() {
        System.out.println("before unpark");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 获取blocker
        System.out.println("Blocker info " + LockSupport.getBlocker((Thread) object));
        // 释放许可 必须把等待获得许可的线程作为参数进行传递,好让此线程继续运行
        LockSupport.unpark((Thread) object);
        // 休眠500ms,保证先执行park中的setBlocker(t, null);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 再次获取blocker
        System.out.println("Blocker info " + LockSupport.getBlocker((Thread) object));
        System.out.println("after unpark");
    }
}

运行结果:

before park
before unpark
Blocker info ParkAndUnparkDemo
after park
Blocker info null
after unpark
说明:本程序先执行park,然后在执行unpark,进行同步,并且在unpark的前后都调用了getBlocker,可以看到两次的结果不一样,并且第二次调用的结果为null,这是因为在调用unpark之后,执行了Lock.park(Object blocker)函数中的setBlocker(t, null)函数,所以第二次调用getBlocker时为null。

同时,先调用unpark,再调用park时,仍能够正确实现同步,不会造成由wait/notify调用顺序不当所引起的阻塞。因此park/unpark相比wait/notify更加的灵活。

原文地址:https://www.cnblogs.com/cherish010/p/8780495.html