• Java多线程之常用的相关方法总结(线程停止、线程休眠、线程礼让、线程优先级、守护线程等等)


    一、线程方法

    setPriority(int newPriority)      更改线程的优先级
    static void sleep(long millis)    在指定的毫秒数内让当前正在执行的线程休眠
    void join()                       等待该线程终止
    static void yield()               暂停当前正在执行的线程对象,并执行其他线程
    void interrupt()                  中断线程,别用这个方式
    boolean isAlive()                 测试线程是否处于活动状态
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    二、线程停止

    1、思路

    不推荐使用JDK提供的stop( )、destroy( )方法
    推荐线程自己停止,使用一个标志位进行终止变量,当flag = false,则终止线程运行。

    2、样例

    package com.example.multithreading.demo5;
    
    //1、建议线程正常停止 ----> 利用次数,不建议死循环
    //2、建议使用标志位 ----> 设置一个标志位
    //3、不要使用stop或者destroy等过时,或者JDK不建议使用的方法
    public class StopTest implements Runnable {
    
        // 1、设置一个标识位
        private boolean flag = true;
    
        @Override
        public void run() {
            int i = 0;
            while (flag) {
                System.out.println("run Thread " + i++);
            }
        }
    
        // 2、设置一个公开的方法停止线程,转换标志位
        public void stop() {
            this.flag = false;
        }
    
        public static void main(String[] args) {
            StopTest stopTest = new StopTest();
    
            new Thread(stopTest).start();
    
            for (int i = 0; i < 100; i++){
                System.out.println("i: " + i);
                if (i == 90){
                    // 调用stop方法切换标志位,让线程停止
                    stopTest.stop();
                    System.out.println("线程该停止了");
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    结果
    在这里插入图片描述

    三、线程休眠(sleep)

    1、思路

    sleep (时间)指定当前线程阻塞的毫秒数
    sleep存在异常InterruptedException
    sleep时间达到后线程进入就绪状态
    sleep可以模拟网络延时,倒计时
    每一个对象都有一个锁,sleep不会释放锁

    2、样例

    package com.example.multithreading.demo6;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    // 模拟倒计时
    public class SleepTest {
    
        public static void main(String[] args) {
            // 打印当前系统时间
            // 获取系统当前时间
            Date startTime = new Date(System.currentTimeMillis());
    
            while(true) {
                try {
    //            tenDown();
                    Thread.sleep(1000);
                    System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
                    // 更新当前时间
                    startTime = new Date(System.currentTimeMillis());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        // 模拟倒计时
        public static void tenDown() throws InterruptedException{
            int num = 10;
    
            while(true){
                Thread.sleep(1000);
                System.out.println(num--);
                if(num<=0){
                    break;
                }
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    结果
    在这里插入图片描述

    四、线程礼让(yield)

    1、思路

    礼让线程,让当前正在执行的线程暂停,但不阻塞
    将线程从运行状态转为就绪状态
    礼让使cpu重新调度,但不一定成功。

    2、样例

    package com.example.multithreading.demo7;
    
    // 测试礼让线程
    // 礼让不一定成功
    public class YieldTest {
    
        public static void main(String[] args) {
            MyYield myYield = new MyYield();
            new Thread(myYield, "a").start();
            new Thread(myYield, "b").start();
    
        }
    }
    
    class MyYield implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "线程开始执行");
            // 礼让
            Thread.yield();
            System.out.println(Thread.currentThread().getName() + "线程停止执行");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    结果
    在这里插入图片描述

    五、线程强制执行(join)

    1、思路

    join合并线程,待此线程执行完后,再执行其他线程,其他线程阻塞。

    2、样例

    package com.example.multithreading.demo8;
    
    public class JoinTest implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程join进来:" + i);
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            JoinTest joinTest = new JoinTest();
            Thread thread = new Thread(joinTest);
            thread.start();
    
            // 主线程
            for (int i = 0; i < 15; i++) {
                if(i==5){
                    // 插队
                    thread.join();
                }
                System.out.println("主线程:" + i);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    结果
    在这里插入图片描述

    六、观测线程状态

    1、相关概念

    一个线程可以在给定的时间点处于一个状态。这些状态是不反映任何操作系统状态的虚拟机状态。

    // 线程状态
    NEW
    尚未启动的线程处于此状态
    RUNNABLE
    在Java虚拟机中执行的线程处于此状态
    BLOCKED
    被阻塞等待监视器锁定的线程处于此状态
    WAITING
    正在等待另一个线程执行特定动作的线程处于此状态
    TIMED_WAITING
    正在等待另一个线程执行动作达到指定等待时间的线程处于此状态
    TERMINATED
    已退出的线程处于此状态
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、样例

    package com.example.multithreading.demo9;
    
    // 观察测试线程的状态
    public class StateTest {
    
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(() -> {
                for (int i = 0; i < 2; i++){
                    try{
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                       e.printStackTrace();
                    }
                }
                System.out.println("/");
            });
    
            // 观察状态
            Thread.State state = thread.getState();
            System.out.println(state);
    
            // 观察启动后
            thread.start();
            // 启动线程
            state = thread.getState();
            System.out.println(state);
    
            // 只要线程不终止,就一直输出状态
            while (state != Thread.State.TERMINATED){
                Thread.sleep(100);
                // 更新线程状态
                state = thread.getState();
                // 输出状态
                System.out.println(state);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    结果
    在这里插入图片描述

    七、线程的优先级

    1、流程

    Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行。
    线程的优先级用数字表示,范围从1~10
    Thread.MIN_PRIORITY = 1;
    Thread.MAX_PRIORITY = 10;
    Thread.NORM_PRIORITY = 5;
    使用以下方式改变或获取优先级
    getPriority() .setPriority(int xxx)
    优先级低只是意味着获得调度的概率低,并不是优先级低就不会被调用了(得看cpu的调度)

    2、样例

    package com.example.multithreading.demo10;
    
    // 测试线程的优先级
    public class PriorityTest {
    
        public static void main(String[] args) {
            // 主线程默认优先级
            System.out.println(Thread.currentThread().getName() + "-->" + Thread.currentThread().getPriority());
    
            Priority priority = new Priority();
    
            Thread t1 = new Thread(priority);
            Thread t2 = new Thread(priority);
            Thread t3 = new Thread(priority);
            Thread t4 = new Thread(priority);
            Thread t5 = new Thread(priority);
            Thread t6 = new Thread(priority);
    
            // 先设置优先级,再启动
            t1.start();
    
            t2.setPriority(1);
            t2.start();
    
            t3.setPriority(4);
            t3.start();
    
            t4.setPriority(Thread.MAX_PRIORITY);
            t4.start();
    
            t5.setPriority(8);
            t5.start();
    
            t6.setPriority(7);
            t6.start();
        }
    }
    
    class Priority implements Runnable{
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "-->" + Thread.currentThread().getPriority());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    结果
    在这里插入图片描述

    八、守护线程

    1、概念

    线程分为用户线程和守护线程
    虚拟机必须确保用户线程执行完毕
    虚拟机不用等待守护线程执行完毕

    2、样例

    package com.example.multithreading.demo11_Daemon;
    
    public class DaemonTest {
    
        public static void main(String[] args) {
            God god = new God();
            People people = new People();
    
            Thread thread = new Thread(god);
            // 默认是false表示是用户线程,现在为true,表示是守护线程
            thread.setDaemon(true);
    
            // 守护线程启动
            thread.start();
    
            // 用户线程启动
            new Thread(people).start();
    
        }
    }
    
    class God implements Runnable{
    
        @Override
        public void run() {
            while (true) {
                System.out.println("守护线程!!!");
            }
        }
    }
    
    class People implements Runnable{
    
        @Override
        public void run() {
            for (int i = 0; i < 10; i++){
                System.out.println("主线程!!!");
            }
            System.out.println("GoodBye World");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    结果
    在这里插入图片描述

  • 相关阅读:
    C语言for循环高手小技巧
    排序进阶----快速排序
    文件上传基础详解
    线性代数学习笔记10-3:奇异值分解SVD(从四个子空间角度理解)
    Day43——约束条件之主键与外键
    vue3学习之路-准备工作
    docker-本地部署-后端
    JDBC学习笔记
    rust的排序
    Hadoop-sqoop
  • 原文地址:https://blog.csdn.net/qq_46106857/article/details/128181887