icode icode
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

iqqcode

保持对技术的探索实践与热爱
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaSE

    • 面向对象

    • 常用API

    • 集合类

    • 多线程

      • Thread

        • 进程与线程
        • 黄牛卖票和模拟龟兔赛跑问题分析
        • 线程常用方法
          • 线程停止及守护线程
          • synchronized关键字解决线程安全问题
          • synchnized原理及优化
          • 线程间的通信
          • 死锁
          • Lock体系
          • ReentrantLock
          • 线程池使用
          • 线程池原理及配置
          • Java线程池的四种用法与使用场景
          • ThreadLocal
        • JUC

      • JDK8新特性

      • IO流

      • JVM

    • JavaWeb

    • JavaEE

    • JavaTopic

    • 设计模式

    • 计算机基础

    • Java后端
    • JavaSE
    • 多线程
    • Thread
    iqqcode
    2021-06-17
    目录

    线程常用方法

    在这里插入图片描述

    # 1. 获取并设置线程名称

    取得当前JVM中正在执行的线程对象 静态方法直接调用

    Thread.currentThread.getName(); //获取当前线程的名称
    

    线程命名的两种方式:

    在创建线程时通过构造方法来传入名称

    new Thread(run,"线程A").start();
    

    通过set方法来设置线程名称


    在这里插入图片描述

    • sleep:抱着资源在睡觉
    • yield: 文明礼让有先序
    • join: 插队优先是大哥

    # 2. 线程休眠-sleep

    sleep(long time<毫秒>)

    sleep方法是静态方法,直接通过Thread类名称来调用。在哪个线程中调用,就休眠当前线程

    • 让线程暂缓执行,sleep()会让当前线程从RUNNING进入到TIME_WAITTING状态,时间到达后处于就绪状态,并不是出于运行状态
    • sleep方法会让当前线程立即交出CPU,但不会释放对象锁
    • interrupt()可以打断正在睡眠的线程,此时sleep方法会抛出InterruptedException
    • sleep可以模拟网络延时,倒计时等,要精确控制时间单位用TimeUnit

    在这里插入图片描述


    # 3. 线程让步-yield

    Thread.yield()方法作用是:当前线 程暂停执行,让出CPU给他线程。

    yield是让当前运行线程回到就绪状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。

    但是,礼让却不一定能够成功,实际中无法保证yield达到让步目的,还取决于操作系统的任务调度器。

    结论:yield从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果,礼让不一定会成功。

    在这里插入图片描述

    【yield要点归纳】

    • 暂停当前正在执行的线程对象,并执行其他线程(只供相同优先级的线程使用)
    • 当前线程不会立即交出CPU,不释放锁,交出时间由系统调度
    • 礼让不一定成功(当前礼让的线程有可能再次被调度)
    • 从运行状态返回就绪状态

    # 案例一

    class ThreadYield implements Runnable {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "-->开始执行");
            Thread.yield();
            System.out.println(Thread.currentThread().getName() + "<--结束执行");
        }
    }
    
    public class ThreadYeild {
        public static void main(String[] args) {
            ThreadYield ty = new ThreadYield();
            new Thread(ty,"A线程").start();
            new Thread(ty,"B线程").start();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    礼让失败:

    B线程被CPU调度,遇到了yield方法礼让,回到就绪态。此时,线程B再次被CPU调度,B线程结束执行 在这里插入图片描述

    礼让成功:

    B线程被CPU调度,遇到了yield方法礼让,回到就绪态。此时,线程A被CPU调度,A线程开始执行

    在这里插入图片描述

    # 案例二

    【线程让步测试】

    • 在线程2中调用yield方法, 将线程2的调度时间分给线程1
    • 最终 [线程A] count1 > count2 [线程B]
    public class YieldTest {
        public static void main(String[] args) {
            new Thread(() -> {
                int count1 = 0;
                for(;;) System.out.println("----->[1]" + (count1++));
            }, "线程A").start();
    
            new Thread(() -> {
                int count2 = 0;
                for(;;) {
                    Thread.yield();
                    System.out.println("                 ----->[2]" + (count2++));
                }
            }, "线程B").start();
    
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    image-20200817185953998

    但是,结果并不一定差别很大。线程的调度最终取决于操作系统的任务调度器。

    image-20200817185724874



    # 4. 线程等待-join

    • 若线程1需要等待线程2执行完毕后再恢复执行,可以在线程1中调用线程2的join();

    • 在哪个线程中调用,哪个线程被阻塞,等待插队的线程执行完毕后当前线程再恢复执行

    • 从运行态到阻塞态会释放锁

    在这里插入图片描述 通过一段代码来验证一下

    • 在A线程中让线程B插队(调用线程B的join方法),那么线程A阻塞,直到线程B执行完毕,
    • 线程A继续执行(回到就绪)
    public class ThreadJoin implements Runnable{
    
        @Override
        public void run() {
            for (int i = 0; i < 500; i++) {
                System.out.println(Thread.currentThread().getName() + "插队线程来了-->" + i);
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            ThreadJoin tj = new ThreadJoin();
            Thread thread = new Thread(tj);
            thread.start();
            //主线程任务
            for (int i = 0; i < 100; i++) {
                if (i == 90) {
                    thread.join();
                }
                System.out.println("main线程执行" + i);
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    在这里插入图片描述

    在这里插入图片描述

    主线程在运行中,当i = 90时Thread-0插队。此时主线程被阻塞,Thread-0执行完成后,主线程继续执行。

    编辑 (opens new window)
    上次更新: 2021/06/27, 10:49:09
    黄牛卖票和模拟龟兔赛跑问题分析
    线程停止及守护线程

    ← 黄牛卖票和模拟龟兔赛跑问题分析 线程停止及守护线程→

    最近更新
    01
    匿名内部类
    10-08
    02
    函数式接口
    10-08
    03
    ARouter-Kotlin踩坑
    10-05
    更多文章>
    Theme by Vdoing | Copyright © 2021-2023 iqqcode | MIT License | 备案号-京ICP备2021028793号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×