JUC之LockSupport

一、LockSupport

1、是什么

LockSupport是线程阻塞和唤醒的工具类。
LockSupport是通过park()和unpark()实现线程等待唤醒。
LockSupport类使用了Permit(许可)的概念来阻塞和唤醒线程的。每个线程都有一个许可。

2、源码

public static void park() {
   UNSAFE.park(false, 0L);
}
public static void unpark(Thread thread) {
	if (thread != null)
        UNSAFE.unpark(thread);
}

底层通过调用unsafe调用外部 C++,采用 CAS 算法。

二、JUC 之 3 中线程阻塞和唤醒

方式一:synchronized

wait和notify方法,必须要在同步块或者方法里面,且成对出现使用,先wait后notify。

方式二:lock

Condition中的线程等待和唤醒方法,需要先获取锁,且先await后signal。

方式三:LockSupport

无锁块要求,因为它本身带锁;
唤醒和阻塞没有顺序,LockSupport一样支持,因为它是通过许可来进行阻塞和唤醒的。
调用park()时:无许可,进行线程阻塞;
调用unpark()时:有许可,唤醒被阻塞的线程。

针对上面 3 种线程的阻塞和唤醒的方式提供一下代码案例:

/**
 * @descpription: 线程的阻塞和唤醒
 * @date 2024/6/12
 */
public class LockSupportDemo {
    public static void main(String[] args) {
//        waitAndNotifyAll();
//        awaitAndSignalAll();
        parkAndUnPark();
    }

    private static void awaitAndSignalAll() {
        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        new Thread(() -> {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + "\t come in");
                try {condition.await();} catch (InterruptedException e) {throw new RuntimeException(e);}
                try {TimeUnit.MILLISECONDS.sleep(400);} catch (InterruptedException e) {throw new RuntimeException(e);}
                System.out.println(Thread.currentThread().getName() + "\t t1 被唤醒");
            } finally {
                lock.unlock();
            }
        }, "t1").start();

        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}

        new Thread(() -> {
            try {
                lock.lock();
                condition.signalAll();
                System.out.println(Thread.currentThread().getName() + "\t t2 唤醒t1");
            } finally {
                lock.unlock();
            }
        }, "t2").start();
    }

    private static void waitAndNotifyAll() {
        final Object obj = new Object();
        new Thread(() -> {
            synchronized (obj) {
                System.out.println(Thread.currentThread().getName() + "\t come in");
                try {obj.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}
                try {TimeUnit.MILLISECONDS.sleep(400);} catch (InterruptedException e) {throw new RuntimeException(e);}
                System.out.println(Thread.currentThread().getName() + "\t t1 被唤醒");
            }
        }, "t1").start();

        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}

        new Thread(() -> {
            synchronized (obj){
                obj.notifyAll();
                System.out.println(Thread.currentThread().getName() + "\t t2 唤醒t1");
            }
        }, "t2").start();
    }

    private static void parkAndUnPark() {
        Thread t1 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t come in");
            LockSupport.park();
            System.out.println(Thread.currentThread().getName() + "\t t1 被唤醒");
        }, "t1");
        t1.start();

        try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}

        new Thread(() -> {
            LockSupport.unpark(t1);
            System.out.println(Thread.currentThread().getName() + "\t t2 唤醒t1");
        }, "t2").start();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值