13-线程休眠和指定唤醒:LockSupport

目录

1.LockSupport.park():休眠当前线程

2.LockSupport.unpark(线程对象):唤醒某一个指定的线程

3.扩展:LockSupport.parkUntil(long)等待最大时间是一个固定时间

4.LockSupport和Interrupt

5.LockSupport VS wait

相同点:

①二者都能使线程进入休眠状态。

②二者在不传递参数的情况下,都会让线程进入WAITING无限期等待状态。

不同点:

①LockSupport使用时不需要加锁,不需要配合synchronized一起使用;而wait需要配合synchronized一起使用。

②LockSupport不会抛出Interrupt的异常,而wait会。

③LockSupport可以指定某一个线程进行唤醒,而wait和notify不行。

PS:线程休眠4种方式:


有wait和notify是因为sleep只能到点之后再被唤醒,不能主动唤醒。

上述方法的问题:在调用notify时会随机唤醒,无法唤醒指定的某一个线程,不能把握线程唤醒的顺序。

使⽤ LockSupport 也可以使线程休眠和唤醒,它包含两个主要的⽅法↓

注:LockSupport 无需配合 synchronized 使用。

1.LockSupport.park():休眠当前线程

import java.util.concurrent.locks.LockSupport;

public class LockSupportDemo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("线程1:开始执行");
            LockSupport.park();
            System.out.println("线程1:结束执行");
        },"线程1");
        t1.start();
    }
}

2.LockSupport.unpark(线程对象):唤醒某一个指定的线程

import java.util.concurrent.locks.LockSupport;

public class LockSupportDemo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("线程1:开始执行");
            LockSupport.park();
            System.out.println("线程1:结束执行");
        },"线程1");

        Thread t2 = new Thread(() -> {
            System.out.println("线程2:开始执行");
            LockSupport.park();
            System.out.println("线程2:结束执行");
        },"线程2");

        Thread t3 = new Thread(() -> {
            System.out.println("线程3:开始执行");
            LockSupport.park();
            System.out.println("线程3:结束执行");
        },"线程3");

        t1.start();
        t2.start();
        t3.start();

        Thread.sleep(1000);
        System.out.println();
        LockSupport.unpark(t1); //唤醒线程1开始执行

        Thread.sleep(1000);
        LockSupport.unpark(t2); //唤醒线程2开始执行

        Thread.sleep(1000);
        LockSupport.unpark(t3); //唤醒线程3开始执行
    }
}

3.扩展:LockSupport.parkUntil(long)等待最大时间是一个固定时间

import java.time.LocalDateTime;
import java.util.concurrent.locks.LockSupport;

public class LockSupportDemo2 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            System.out.println("线程1:开始执行 |" + LocalDateTime.now());
            //当前时间 + 超时时间(唤醒时间)
            LockSupport.parkUntil(System.currentTimeMillis() + 3000);//3000ms代表3s,表示3s之后恢复执行
            System.out.println("线程1:结束执行 |" + LocalDateTime.now());
        },"线程1");
        t1.start();
    }
}

4.LockSupport和Interrupt

之前的 sleep/TimeUnit/wait 写法都需要加try-catch包裹来接收Interrupt异常,写法不够优雅;而 LockSupport.park/parkUntil在休眠时不需要try-catch包裹,不需要接收 Interrupt 异常。

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}

try {
    TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
    e.printStackTrace();
}

synchronized (lock){
    try {
        lock.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

LockSupport.park();
LockSupport.parkUntil(1000 + System.currentTimeMillis());

LockSupport 不会抛出 Interrupt 的异常,但可以监听到 Interrupt 的通知:

import java.util.concurrent.locks.LockSupport;

public class ThreadDemo20 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            Thread currThread = Thread.currentThread();
            System.out.println("线程中止状态:" + currThread.isInterrupted());
            LockSupport.park();
            System.out.println("线程中止状态:" + currThread.isInterrupted());
        });
        t1.start();

        Thread.sleep(1000);
        System.out.println("中止线程");
        t1.interrupt();
        LockSupport.unpark(t1);
    }
}

5.LockSupport VS wait

相同点:

①二者都能使线程进入休眠状态。

②二者在不传递参数的情况下,都会让线程进入WAITING无限期等待状态。

不同点:

①LockSupport使用时不需要加锁,不需要配合synchronized一起使用;而wait需要配合synchronized一起使用。

②LockSupport不会抛出Interrupt的异常,而wait会。

③LockSupport可以指定某一个线程进行唤醒,而wait和notify不行。

PS:线程休眠4种方式:

  1. sleep(传参设置休眠时间;不可唤醒)
  2. TimeUnit(传参设置休眠时间;不可唤醒)
  3. wait/notify/notifyAll(可传参设置休眠时间,也可不传参无限等待;可以唤醒)
  4. LockSupport.park()/parkUntil(long)/unpark(thread)(parkUntil可传参设置休眠时间;park不传参无限等待;unpark传参唤醒指定线程)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值