2024年最新【多线程进阶】如何保证唱跳rap打篮球的顺序,大厂面试必备技能

最后

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。
在这里插入图片描述

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 基于join

  • 基于volatile

  • 基于synchronized

  • 基于reentrantLock

  • 基于countDownLatch

不多逼逼,上才艺

先来个入门的:join


join是Thread类的方法,底层基于wait+notify,你可以把这个方法理解成插队,谁调用谁插队,但有局限性

适用于线程较少的场景,如果线程多了会造成无限套娃,有点麻烦,不够优雅

public class JoinTest {

// 用来记录啊鸡学习时间

static double year;

public static void main(String[] args) {

//线程A,练习唱跳rap

Thread threadA = new Thread(() -> {

for (year = 0.5; year <= 5; year += 0.5) {

System.out.println(“开始练习唱跳rap:已练习” + year + “年”);

try {

Thread.sleep(288);

} catch (InterruptedException e) {

e.printStackTrace();

}

//众所周知,练习两年半即可出道

if (year == 2.5) {

System.out.println(“===========================>练习时长两年半,出道!!!”);

//留意下这个break,想想如果不break会怎样

break;

}

}

});

//线程B,练习打篮球

Thread threadB = new Thread(() -> {

try {

// 让threadA线程插队,threadB执行到这儿时会被阻塞,直到threadA执行完

threadA.join();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(“开始练习打篮球”);

});

// 启动线程

threadA.start();

threadB.start();

}

}

在这里插入图片描述

不管运行多少次,结果都一样,今天就是耶稣来了也一样,我说的

如果不break,那自然是等threadA执行完了threadB才开始执行

在这里插入图片描述

通过volatile


这种实现比较简单,也很好理解,但是性能不咋地,会抢占很多cpu资源,如非必要,不要用

public class VolatileTest {

//定义一个共享变量用来线程间通信,注意用volatile修饰,保证它内存可见

static volatile boolean flag = false;

static double year;

public static void main(String[] args) {

//线程A,练习唱跳rap

Thread threadA = new Thread(() -> {

while (true) {

if (!flag) {

for (year = 0.5; year <= 5; year += 0.5) {

System.out.println(“开始练习唱跳rap:已练习” + year + “年”);

try {

Thread.sleep(288);

} catch (InterruptedException e) {

e.printStackTrace();

}

//众所周知,练习两年半即可出道

if (year == 2.5) {

System.out.println(“===========================>练习时长两年半,出道!!!”);

// 通知threadB你可以执行了

flag = true;

//同样留意这个break

break;

}

}

break;

}

}

});

//线程B,练习打篮球

Thread threadB = new Thread(() -> {

while (true) {

// 监听flag

if (flag) {

System.out.println(“开始练习打篮球”);

break;

}

}

});

threadA.start();

threadB.start();

}

}

结果与上面第一个一样,就不展示了

关于break,我这里先不说,你先猜猜结果,再复制demo去跑跑,一定要动手

synchronized、wait()、notify()三件套


wait() 和 notify()都是Object类的通讯方法,注意一点,wait和 notify需搭配synchronized使用,注意,notify不会释放锁,至于不会释放锁体现在哪儿,这个demo下面有说明

public class SynchronizedTest {

static double year;

public static void main(String[] args) {

SynchronizedTest sync= new SynchronizedTest();

sync.execute();

}

public void execute() {

//线程A,练习唱跳rap

Thread threadA = new Thread(() -> {

synchronized (this) {

for (year = 0.5; year <= 5; year += 0.5) {

try {

System.out.println(“开始练习唱跳rap:已练习” + year + “年”);

Thread.sleep(288);

if (year == 2.5) {

System.out.println(“===========================>练习时长两年半,出道!!!”);

//唤醒等待中的threadB,但threadB不会立马执行,而是等待threadA执行完,因为notify不会释放锁

notify();

break;

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

});

//线程B,练习打篮球

Thread threadB = new Thread(() -> {

synchronized (this) {

try {

wait();

System.out.println(“开始练习打篮球”);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

//注意,一定要先启动B,不然会导致B永远阻塞

threadB.start();

threadA.start();

}

}

这个threadA里面的break一定要多想想,跑一跑你就知道啥叫不会释放锁

如果没有break,threadA在唤醒threadB后,会继续执行自己的逻辑,等自己执行完了才会释放锁,这时候threadB才开始执行

基于ReentrantLock


ReentrantLock是juc包下的并发工具,也能实现,但相对复杂,需结合Condition的await和signal,底层原理有点像上面的wait和notify

这里留个课后作业:思考一下为什么unlock要放在finally里面?

public class ReentrantLockTest {

static double year;

public static void main(String[] args) {

//实例化一个锁和Condition

ReentrantLock lock = new ReentrantLock();

Condition condition = lock.newCondition();

//线程A,练习唱跳rap

Thread threadA = new Thread(() -> {

lock.lock();

try {

for (year = 0.5; year <= 5; year += 0.5) {

System.out.println(“开始练习唱跳rap:已练习” + year + “年”);

Thread.sleep(288);

最后

光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性

Java面试宝典2021版

最常见Java面试题解析(2021最新版)

2021企业Java面试题精选

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

试题解析(2021最新版)

[外链图片转存中…(img-xVKh8mSb-1715232631829)]

[外链图片转存中…(img-FCazTKao-1715232631830)]

2021企业Java面试题精选

[外链图片转存中…(img-grhBTxJC-1715232631830)]

[外链图片转存中…(img-wdNUBkyu-1715232631831)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值