sleep方法是在Thread类中的一个静态方法,当一个线程调用了sleep方法,被调用的那个线程就会暂时的让出指定时间的CPU执行权,在这段时间也不会参与CPU的调度,当时间到了之后,就会重新回到就绪状态,等待CPU的再次调度,注意是就绪状态,而不是重新拿回CPU的执行权。并且,在休眠期间,只是会让出CPU的执行权,但是之前获得的锁资源,还是继续持有,等CPU调度到该线程重新获取到执行权的时候,就会继续运行sleep之后的代码。接下来用一个例子来说明Sleep期间不会放弃锁资源

public class SleepDemo {
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
Thread one = new Thread(() -> {
lock.lock();
System.out.println("线程A准备被Sleep"); //1
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程A被唤醒"); //2
lock.unlock();
});
Thread two = new Thread(() -> {
lock.lock();
System.out.println("线程B准备被Sleep"); //3
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程B被唤醒"); //4
lock.unlock();
});
one.start();
two.start();
}
}

在上面的代码中,new了两个线程,但是只有一个锁资源lock,如果sleep期间会释放锁资源的话,那么输出结果应当是交替输出的,因为在执行代码1的时候,会被剥夺执行权,那么线程2将会拿到锁,但是事实真的是这样吗,看输出结果

线程A准备被Sleep

线程A被唤醒

线程B准备被Sleep

线程B被唤醒

可以看到,线程A被sleep的时候,线程2执行,想要获取锁I资源lock,但是发现lock被占有了,只好阻塞,然后线程1的休眠时间到了,重新获取执行权,继续执行sleep之后的代码,然后释放锁,然后线程2拿到锁,执行后续代码。通过上面的代码就可以看出,sleep期间是不会释放锁资源的,只是暂时的让出了cpu的执行权

创建多线程程序的第二种方式-实现Runnable接口

java.lang. Runnable也是非吊军儿的一种,我们只需要重与run万法即可。

步骤如下∶

  1.定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

  ⒉创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

  3.调用线程对象的start()方法来启动线程

public class Demo_Runnable implements Runnable{
@Override
public void run() {
for(int i = 0; i < 20; i++){
System.out.println(Thread.currentThread().getName()+"--》"+i);
}
}
public static void main(String[] args) {
Demo_Runnable demo_runnable = new Demo_Runnable();
Thread thread = new Thread(demo_runnable); thread.start(); for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i); } }
}
// 创建线程2: 实现Runnable接口,重写run()方法,执行线程需要丢入的runnable接口实现类,调用start()方法。
public class TestThread3 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
// run方法线程体
System.out.println("我在看代码-----" + i);
}
} public static void main(String[] args) {
// 创建Runnable接口的实现类对象
TestThread3 testThread3 = new TestThread3();
// 创建线程,对象通过线程对象开启线程
// Thread thread = new Thread(testThread3);
// thread.start(); new Thread(testThread3).start(); for (int i = 0; i < 1000; i++) {
System.out.println("我在学习多线程-----" + i);
}
}
}

Thread类的常用方法_sleep和创建多线程程序的第二种方式_实现Runnable接口的更多相关文章

  1. Thread类的常用方法_sleep和创建多线程程序的第二种方式实现Runnable接口

    public static void sleep(long millis);//使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行). 毫秒数结束后线程继续执行 package com.yang.T ...

  2. 创建多线程程序的第一种方式_创建Thread类的子类

    创建多线程程序的第一种方式:创建Thread类的子类java.lang.Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类 实现步骤: 1.创建一个Thread类的子类 ...

  3. 主线程和创建多线程程序的第一种方式_创建Thread类的子类

    /** * 主线程:执行主方法的线程(main) * 单线程程序:在java程序中只有一个线程 * 执行从main方法开始,从上倒下依次执行 */ public class Demo01MainThr ...

  4. Java创建线程的第二种方式:实现runable接口

    /*需求:简单的卖票程序多个窗口买票 创建线程的第二种方式:实现runable接口 *//*步骤1.定义类实现Runable接口2.覆盖Runable接口中的run方法    将线程要运行的代码存放在 ...

  5. 50、多线程创建的三种方式之实现Runnable接口

    实现Runnable接口创建线程 使用Runnable创建线程步骤: package com.sutaoyu.Thread; //1.自定义一个类实现java.lang包下的Runnable接口 cl ...

  6. Thread类的常用方法----多线程基础练习

    创建多线程程序的第一种方式----继承Thread类 常用API 构造方法 public Thread() :分配一个新的线程对象. public Thread(String name) :分配一个指 ...

  7. 多线程-创建线程第二种方式-实现Runnable接口-细节和好处

    1 package multithread2; 2 3 /* 4 * 创建线程的第一种方法:继承Thread类 5 * 6 * 创建线程的第二种方式:实现Runnable接口 7 * 8 * 1,定义 ...

  8. 创建线程的第二种方式------实现Runnable接口的方式

    package cn.itcast.demo16.Demo07.Runnable;/** * @author newcityman * @date 2019/7/22 - 23:17 */public ...

  9. 创建多线程的方式&Thread类的常用方法

    创建多线程的第一种方式:继承java.lang.Thread类 注意:1.一个线程只能执行一次start() 2.不能通过Thread实现类对象的 run()去启动一个线程 3.增加加一个线程,需要新 ...

随机推荐

  1. postgreSQL使用sql归一化数据表的某列,以及出现“字段 ‘xxx’ 必须出现在 GROUP BY 子句中或者在聚合函数中”错误的可能原因之一

    前言: 归一化(区别于标准化)一般是指,把数据变换到(0,1)之间的小数.主要是为了方便数据处理,或者把有量纲表达式变成无量纲表达式,便于不同单位或量级的指标能够进行比较和加权. 不过还是有很多人使用 ...

  2. Vert.X CompositeFuture 用法

    CompositeFuture 是一种特殊的 Future,它可以包装一个 Future 列表,从而让一组异步操作并行执行:然后协调这一组操作的结果,作为 CompositeFuture 的结果.本文 ...

  3. 『现学现忘』Git基础 — 24、Git中查看历史版本记录

    目录 1.查看详细的历史版本记录 2.简化显示历史版本记录 3.历史版本记录常用操作 (1)指定查看最近几次提交的内容 (2)以简单图形的方式查看分支版本历史 (3)翻页与退出 4.查看分支相关的版本 ...

  4. django-rest-framework 基础三 认证、权限和频率

    django-rest-framework 基础三 认证.权限和频率 目录 django-rest-framework 基础三 认证.权限和频率 1. 认证 1.1 登录接口 1.2 认证 2. 权限 ...

  5. 什么是Docker容器?(全面了解使用)

    一:为什么需要Docker容器? 1.引入 1.1麻烦的环境部署 1.在软件开发中,最麻烦的事情之一就是环境配置.在正常情况下,如果要保证程序能运行,我们需要设置好操作系统,以及各种库和组件的安装. ...

  6. Redis设计与实现3.3:集群

    集群 这是<Redis设计与实现>系列的文章,系列导航:Redis设计与实现笔记 集群中的节点 创建集群 通过 CLUSTER NODE 命令可以查看当前集群中的节点.刚启动时,默认每一台 ...

  7. 165. Compare Version Numbers - LeetCode

    Question 165. Compare Version Numbers Solution 题目大意: 比较版本号大小 思路: 根据逗号将版本号字符串转成数组,再比较每个数的大小 Java实现: p ...

  8. linux篇-linux LAMP yum版安装

    LAMP(linux.apache.mysql.php),是四个套件的合成,简单讲就是要把php运行在linux上,需要依赖apache和mysql数据库. 1 准备好一个linux系统(centos ...

  9. 使用 gitbook 制作自己的 html 文档

    使用 gitbook 制作自己的 html 文档 步骤如下 npm install gitbook-cli -g // 全局安装 gitbook-cli <span style="te ...

  10. 每天一个 HTTP 状态码 102

    102 Processing 102 Processing 是用于 WebDAV协议 请求的状态码. 这个状态码表示服务器已经收到了客户端的请求,正在处理,但暂时还没有可接触的响应.可以用于防止客户端 ...