并发编程——GuardedObject

文章详细探讨了Java中守护对象GuardedObject的使用,如何在业务逻辑处理中实现超时机制,以及Thread.join的类似逻辑。通过实例展示了设置不同超时时间对主线程获取结果的影响。
摘要由CSDN通过智能技术生成

logger.info(“开始处理业务逻辑”);

try {

TimeUnit.SECONDS.sleep(2);

} catch (InterruptedException e) {

e.printStackTrace();

}

logger.info(“业务逻辑处理完毕”);

guardedObject.setResult(new Object());

});

t1.start();

Object result = guardedObject.getResult();

logger.info(“main线程获取到了返回值{}”,result);

在t1中,为了模拟业务操作,特意让线程sleep了2秒,但是就算是这,主线程依然可以正常获取到返回结果:

在这里插入图片描述

接下来,我们加入一个超时机制,为getResult方法添加一个超时时间,如果超过了超时时间,就算是还没有结果,也返回,不再阻塞。

通常的改法是这样的:

在这里插入图片描述

这样改造也确实实现了超时的需求,但是不够严谨,因为没法100%保证在没有返回值的情况下,一定可以等足timeOut毫秒。严谨版如下:

在这里插入图片描述

我们先假设剩余等待时间就是timeOut的值,当wait被唤醒时,先判断timeOut的值是不是0,如果是0,那么只需要判断result的值是不是null就可以了。如果不是0,那么计算剩余等待时间,如果剩余等待时间<=0,那就说明真的是超时了,直接break,如果还有剩余时间,那么判断result是不是null,如果是null,那么继续wait,如果不是null,直接返回result

接下来我们看下程序的运行结果:

  1. 假定业务的处理时间还是2秒,main线程设置超时1秒,结果如下:

在这里插入图片描述

从结果中可以看到,间隔1秒后main线程停止了阻塞,但是没有获取到返回值。

  1. 假定业务的处理时间还是2秒,main线程设置超时3秒,结果如下:

在这里插入图片描述

从结果中可以看到,虽然设置了超时时间为3秒,但是因为t1在2秒后会设置好result的值,所以main线程也只阻塞了2秒。

  1. 假定业务的处理时间还是2秒,main线程设置超时0秒,结果如下:

在这里插入图片描述

这个的结果跟第2次测试的结果是一样,就不啰嗦了。

引申:

Thread.join的超时逻辑也是类似的

完整的代码如下:

package com.example.demo;

import org.junit.jupiter.api.Test;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.boot.test.context.SpringBootTest;

import java.util.concurrent.TimeUnit;

@SpringBootTest

class DemoApplicationTests4 {

/**

  • GuardedObject

  • 线程t1处理一个事物,主线程等待获取事物的处理结果

  • @throws InterruptedException

*/

@Test

void Test1() throws InterruptedException {

Logger logger = LoggerFactory.getLogger(this.getClass());

GuardedObject guardedObject = new GuardedObject();

Thread t1 = new Thread(()->{

logger.info(“开始处理业务逻辑”);

try {

TimeUnit.SECONDS.sleep(2);

} catch (InterruptedException e) {

e.printStackTrace();

}

logger.info(“业务逻辑处理完毕”);

guardedObject.setResult(new Object());

});

t1.start();

logger.info(“main线程开始获取返回值”);

Object result = guardedObject.getResult(TimeUnit.SECONDS.toMillis(0));

logger.info(“main线程获取到了返回值{}”,result);

}

/**

  • 守护对象

*/

static class GuardedObject{

private Object result;

private final Object lock = new Object();

public Object getResult(long timeOut) {

long currentTimeMillis = System.currentTimeMillis();

long remainingTime = timeOut;

synchronized (lock){

while (result==null){

try {

lock.wait(remainingTime);

if (timeOut!=0) {

remainingTime = timeOut-(System.currentTimeMillis()-currentTimeMillis);

if (remainingTime<=0) {

break;

}

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

return result;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

码字不易,觉得有帮助的可以帮忙点个赞,让更多有需要的人看到

又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考

以下是部分内容截图
架构面试专题及架构学习笔记导图.png
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考

以下是部分内容截图
[外链图片转存中…(img-s8pU1FUg-1713670606844)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 26
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值