当前位置: 首页 > news >正文

Java Thread.sleep(),结合例子只学一次

这个sleep的方法大家很常见也很常用,也别是刚开始玩代码的时候,很喜欢测试一些逻辑的时候,sleep一下。

sleep 有啥用: 

让线程在我们要它执行的时候执行,如果我们不要,那就让它睡,不占用 CPU 资源。

那么其实在使用多线程的时候,很容易关联到 锁的使用 ,synchronized 和 Lock这些 。

那么该篇文章其实核心内容是想让大家知道,sleep 与 锁资源之间的关系。

问题: 使用sleep时, 锁资源会释放吗?

示例介绍,一步一步来:

首先我们写下简单的测试代码:
 

public class SleepTest implements Runnable {
    private int count = 1;
    @SneakyThrows
    @Override
    public void run() {
        while (true) {

                if (count < 10) {
                    Thread.sleep(1000);
                }
                System.out.println(Thread.currentThread().getName() + "count=" + count);
                count++;
                if (count > 10) {
                    break;
                }
        }

    }
}

写个测试的调用代码:

    public static void main(String[] args) throws InterruptedException {
        SleepTest sleepTest=new SleepTest();
        Thread thread1=new Thread(sleepTest);
        Thread thread2=new Thread(sleepTest);
        thread1.start();
        thread2.start();

    }

运行效果:

 上面这种是还没涉及到锁的情况,不存在锁资源竞争。那么接下来我们改下代码:
 

    @SneakyThrows
    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                System.out.println("开始了" + Thread.currentThread().getName() + "count=" + count);
                if (count < 10) {
                    Thread.sleep(1000);
                }
                System.out.println("睡醒了" + Thread.currentThread().getName() + "count=" + count);

                count++;
                if (count > 10) {
                    break;
                }
                System.out.println("这时候执行完一轮,即将会释放锁" + Thread.currentThread().getName());
            }
        }

    }

注意了: 这时候我的 synchronized  加在的地方 注意了!

我是加在while里面的 , 大家看下执行效果:


 可以看到,红色是线程 0 ,蓝色是线程1 ,两个线程有交替输出现象。

不是说sleep不会释放锁资源吗?

其实认真看我的代码,我已经打出了一个输出在关键节点:

因为两个线程都进入到了while里面,   synchronized 框住的代码里面有sleep,这时候其实真的是不会释放锁资源的,所以看到
开始了Thread-1count=8
睡醒了Thread-1count=8
这时候执行完一轮,即将会释放锁Thread-1
这三阶段都是一段 一段 输出的 。

然后每一段输出完,锁自动释放。 那就是两个线程自由获取锁资源了。

紧接着,我们把synchronized 放在 while 外面 :

这时候的允许结果,无论执行多少次:

 可以看到都是先拿到锁资源的线程,先进入自己的锁内代码块执行,就算里面sleep了,也不会释放锁资源,只有等到整个 synchronized 框住的代码块 执行完了,才释放锁资源 ; 然后另一个线程才拿的到锁,去执行相关代码块。

Sleep 不会释放 锁资源!

再继续搞多一个例子,也是更加明了: 

    private int count = 1;

    @SneakyThrows
    @Override
    public void run() {
        synctest();

    }

    private synchronized void synctest() throws InterruptedException {

        System.out.println(Thread.currentThread().getName()+"拿到锁!!!!!!!!!!");
        while (true) {

                System.out.println("开始了" + Thread.currentThread().getName() + "count=" + count);
                if (count < 10) {
                    Thread.sleep(100);
                }
                System.out.println("睡醒了" + Thread.currentThread().getName() + "count=" + count);

                count++;
                if (count > 10) {
                    System.out.println(Thread.currentThread().getName()+"大过10了,要出去了");
                    break;
                }

            }
        System.out.println(Thread.currentThread().getName()+"while方法执行完了,把锁释放给别人");

    }
}

 

看看这情况的执行效果 (大家可以自己想一下,看看与实际效果一不一样):
 

    public static void main(String[] args) throws InterruptedException {
        SleepTestNew sleepTest=new SleepTestNew();
        Thread thread1=new Thread(sleepTest);
        Thread thread2=new Thread(sleepTest);
        thread1.start();
        thread2.start();

    }

结果:

 可以看到跟上一次效果一样,先拿到锁资源的线程0, 任意妄为,sleep 休息了很久,但是就是不把锁资源让出来, 别人 线程1 只能等到这个线程完全执行完了,才能拿到锁资源,但是此时count已经大于10了,拿到也没意思,只能根据逻辑出来了。

所以结论 :


Sleep 不会释放 锁资源!

Sleep 不会释放 锁资源!

Sleep 不会释放 锁资源!

ps: lock也是一样效果,就不在写代码举例了。

相关文章:

  • Java ArrayList new出来,默认的容量到底是0还是10 ?
  • Mysql 关于 int(1) 和 int(11) , 我必须要说一下了。
  • SpringCloud 整合注册中心,配置中心 Nacos (九)
  • Springboot 自定义注解AOP实现时间参数格式转换
  • 看什么看啊,你不会还不会抓HTTPS请求报文吧?
  • 做一个合格的开发,从玩转Apipost开始
  • Springboot 整合 企业微信机器人助手推送消息
  • Springboot 同一次调用日志怎么用ID串起来,方便最终查找
  • IDEA 运行Tomcat项目 控制台乱码
  • Springboot 整合 xxljob 使用定时任务调度(新手入门篇)
  • Springboot @SpringBootTest 单元测试执行两次的问题
  • Amazon ElastiCache 飞速搭建缓存服务集群,这才叫快
  • Springboot 整合 xxljob 动态API调度任务(进阶篇)
  • getReader() has already been called for this request
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • 【翻译】babel对TC39装饰器草案的实现
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • ES2017异步函数现已正式可用
  • es6(二):字符串的扩展
  • leetcode386. Lexicographical Numbers
  • LintCode 31. partitionArray 数组划分
  • PHP变量
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 成为一名优秀的Developer的书单
  • 码农张的Bug人生 - 见面之礼
  • 排序(1):冒泡排序
  • 前言-如何学习区块链
  • 如何设计一个微型分布式架构?
  • 深入浅出Node.js
  • const的用法,特别是用在函数前面与后面的区别
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • "无招胜有招"nbsp;史上最全的互…
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • $.ajax()
  • $forceUpdate()函数
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • (转载)OpenStack Hacker养成指南
  • .apk文件,IIS不支持下载解决
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .Net CF下精确的计时器
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .Net MVC + EF搭建学生管理系统
  • .NET 服务 ServiceController
  • .Net8 Blazor 尝鲜
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装