LockSupport

在java.util.concurrent.locks包下
使用java在线API:
https://www.matools.com/api/java8
LockSupport是线程的wait/notify的改良加强版
LOckSupport的park和unpark的作用分别是阻塞线程与解除阻塞线程的事
三种线程的等待/唤醒方法
1.Object对象的wait方法使线程等待,notify方法唤醒线程
注意:不在同一个代码块等待和唤醒功能是不能被用的,会报异常
注意:要等待在前,唤醒在后。如果唤醒在前。等待在后,则线程将会一直等待。
实例1

package com.example.demo.LockTest;

/**
 * 编写wait-notify
 * 注意:wait-notify要在同一个代码块里面
 * 注意:要wait在前,notify在后
 * @author Ric
 */
public class WaitNotifyTest {
    static Object object = new Object();
    public static void main(String[] args) {
        new Thread(()->{
            synchronized (object){
                System.out.println(Thread.currentThread().getName()+"进入");
                try {
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"被唤醒");
            }
        },"线程1").start();

        new Thread(()->{
            synchronized (object){
                object.notifyAll();
                System.out.println(Thread.currentThread().getName()+"通知唤醒所有线程");
            }
        },"线程2").start();
    }
}

结果:

线程1进入
线程2通知唤醒所有线程
线程1被唤醒

2.JUC的Condition里面的await是线程等待,signal唤醒线程
实例2

package com.example.demo.LockTest;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Condition的 Await 与 Signal
 * 注意: lock与 unlock是成对出现
 *       await与signal必须在锁(Lock与unlock)里面
 *       await必须在signal前面,不然线程会一直等待
 * @author Ric
 */
public class AwaitSignalTest {
    static ReentrantLock reentrantLock = new ReentrantLock();
    static Condition condition = reentrantLock.newCondition();
    public static void main(String[] args) {
        new Thread(()->{
            //显示锁需要在加锁后面紧跟 try-catch-finally 进行解锁
            reentrantLock.lock();
            try {
                System.out.println(Thread.currentThread().getName()+"进入ReentrantLock加锁代码块");
                condition.await();
                System.out.println(Thread.currentThread().getName()+"已被唤醒");
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                reentrantLock.unlock();
            }
        },"线程1").start();
        new Thread(()->{
            //显示锁需要在加锁后面紧跟 try-catch-finally 进行解锁
            reentrantLock.lock();
            try {
                condition.signalAll();
                System.out.println(Thread.currentThread().getName()+"进行线程唤醒");
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                reentrantLock.unlock();
            }
        },"线程2").start();
    }
}

展示结果

线程1进入ReentrantLock加锁代码块
线程2进行线程唤醒
线程1已被唤醒

3.LockSupport的park阻塞线程,unpark解除阻塞线程。
lockSupport的park与unpark相当于设置信号量(许可证),许可证不能累加,初始值为0,unpark一次加1,但是不能大于1,park一次减1.但是不能小于0。所以许可证的值只能为0和1.

实例1:

package com.example.demo.LockTest;

import java.util.concurrent.locks.LockSupport;

/**
 * 测试LockSupport的park与unpark
 * 注意:LockSupport的构造方法是私有的  直接通过LockSupport这个类来访问
 * LockSupport直接通过类进行方法访问
 * park()默认许可证为 0    unpark()使许可证为 1   许可证只能为 0 和 1
 * 许可证为 1 表示能唤醒一次该目标线程
 *
 * park() 与 unpark() 没有先后顺序之分
 */
public class LockSupportTest {
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "进入");
            //阻塞 许可证默认为 0
            LockSupport.park();
            System.out.println(Thread.currentThread().getName() + "已被唤醒");
        }, "线程1");
        thread1.start();

        new Thread(()->{
            //许可证为1 就算多次park()许可证还是为1
            //传入要被唤醒的线程,让该线程的许可证为 1,可以被唤醒
            LockSupport.unpark(thread1);
            System.out.println(Thread.currentThread().getName()+"唤醒"+thread1.getName());
        },"线程2").start();
    }
}

示例结果:

线程1进入
线程2唤醒线程1
线程1已被唤醒
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值