多线程JUC 第2季 LockSupport的等待唤醒机制

本文介绍了LockSupport在Java中用于线程阻塞和唤醒的功能,与传统方式如Object.wait(),Condition.await(),和synchronized关键字的对比,展示了如何通过LockSupport实现更灵活的线程控制。
摘要由CSDN通过智能技术生成

一  LockSupport的作用

1.1 locksupport作用

locksupport阻塞当前线程和唤醒指定阻塞的线程。

locksupport是一个线程阻塞工具类,所有的方法都是静态的,可以让线程任务阻塞,阻塞之后也有对应的唤醒方法,归根接底,locksupport调用的是unsafe的native代码。

a)当调用park方法时

b)如果有凭证,则会直接消耗掉这个凭证然后退出。

如果无凭证,就必须阻塞等待凭证可用。

当调用unpark时,他会增加一个凭证,但凭证最多有1个,累加无效。

locksupport和每个使用的他的线程都有1个许可关联。当调用unpark获得一个凭证后,再调用park,就可以消费不会阻塞,但是唤醒两次,阻塞两次;而调用两次park;需要两个凭证;unpark调用2次,也只有1个凭证,故剩余一次的park还会阻塞。 

1.2  实现等待唤醒的3种方式

1.方式1:使用object的wait()方法让线程等待,使用object中的notify()方法唤醒线程。object的wait和notify 必须使用同一把锁,且wait必须优先notify执行,才ok1

2.方式2:使用juc包中的condition的await()方法让线程等待,使用signal()方法唤醒线程。condition中的await和singal 必须放到锁中,且wait必须优先notify执行,才ok1

3.方式3:使用locksupport类可以阻塞当前线程以及唤醒指定被阻塞的线程。locksupport 先执行unpark后执行park,均可以,但是必须成对出现。

如下图:

1.3 实现方式

1.3.1  LockSupport

locksupport 先执行unpark后执行park,均可以,但是必须成对出现。

package com.ljf.thread.lockSupport;

import java.util.concurrent.locks.LockSupport;

/**
 * @ClassName: Huanxing1
 * @Description: TODO
 * @Author: admin
 * @Date: 2024/03/14 23:12:15 
 * @Version: V1.0
 **/
public class Huanxing1 {
    public static void main(String[] args) {
     //   LockSupport lockSupport=
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("t1阻塞");
                LockSupport.park();
                System.out.println("t1释放阻塞...");
            }
        });
        t1.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                LockSupport.unpark(t1);
                System.out.println("唤醒t1");
            }
        }).start();

    }
}

1.3.2  使用Lock 

condition中的await和singal 必须放到锁中,且wait必须优先notify执行,才ok1

1.3.3 使用synchronize

object的wait和notify 必须使用同一把锁,且wait必须优先notify执行,才ok1

public class SynDemo {
    public static void main(String[] args) {
        Object obj=new Object();
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (obj){

                    try {
                        System.out.println("t1等待");
                        obj.wait();
                        System.out.println("t1被释放");
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });

        t1.start();

        Thread t2=new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (obj){
                    try {
                        Thread.sleep(3000);
                        System.out.println("t2通知释放t1");
                        obj.notify();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });

        t2.start();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值