Java多线程实现(三)——线程状态

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在这里插入图片描述
一个线程有图上五种状态,本文将总结狂神视频中改变线程状态的方法。

一、线程停止

  • 方法:通过设置停止标志位,线程调用用户自己写的停止线程的方法,使得线程停止。
  • 实例:当主线程打印输出900次时,将线程Thread停止。
// 线程停止
public class TestStop implements Runnable{
    // 设置停止标志位
    private boolean flag = true;
    @Override
    public void run() {
        int i = 0;
        while (flag){
           System.out.println("running...->" + i++);
        }
    }

    // 设置线程停止方法
    public void stopThread(){
        this.flag = false;
    }

    public static void main(String[] args) {
        TestStop testState = new TestStop();
        new Thread(testState).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("main...->" + i);
            if (i==900){
                testState.stopThread();  // 调用该方法时线程停止,推荐使用让线程自己停止的方法
                System.out.println("testThread is stopped");
            }
        }
    }
}

二、线程休眠

  • 方法:线程通过调用sleep()方法,实现线程休眠。
  • 实例:实现10秒倒计时,每打印一个数字,线程休眠一秒,再打印下一个数字。
// 线程休眠
public class TestSleep{
    public static void main(String[] args) {
        try {
            tenDown();
        } catch (InterruptedException 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;
            }
        }
    }
}

三、线程礼让

  • 内容:线程礼让是指当前cpu正在执行线程A,这是线程B为就绪状态,A就让出cpu资源,从运行态变成就绪态。此时A与B重新竞争cpu资源,谁竞争成功,谁使用cpu资源。
  • 注意:线程礼让不一定成功。即,线程A让出cpu资源后,与线程B再竞争cpu资源,B不一定能拿的到cpu资源。
  • 方法:线程调用yeild()方法,实现线程礼让。
  • 实例:线程A礼让线程B
// 线程礼让
public class TestYeild implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"线程开始");
        Thread.yield();
        System.out.println(Thread.currentThread().getName()+"线程结束");
    }

    public static void main(String[] args) {
        TestYeild testYeild = new TestYeild();
        new Thread(testYeild, "A").start();
        new Thread(testYeild, "B").start();
    }
}

四、线程强制执行

  • 内容:可以将其理解为“插队”,然后优先执行该线程
  • 方法:调用join()方法,实现线程强制执行
  • 实例:在主线程main执行输出到第100次时,线程thread进行插队,强制执行500次,之后再进行主线程。
public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 500; i++) {
            System.out.println("线程进来插队,优先执行" + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start();
        for (int i = 0; i < 200; i++) {
            if (i == 100){
                thread.join();
			}
            System.out.println("main执行中" + i);
        }
    }
}

五、观测线程状态

  • 线程的状态有:
    1)NEW:尚未启动的线程处于该状态。
    2)RUNNABLE:在java虚拟机中执行的线程处于此状态。
    3)BLOCKED:被阻塞等待监视器锁定的线程处于此状态。
    4) WAITING:正在等待另一个线程执行特定动作的线程处于此状态。
    5)TIMED_WAINTING:正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
    6)TERMINATED:已退出的线程处于此状态。
  • 方法:线程调用getState()方法获取线程状态。

六、设置线程优先级

  • 内容:线程的优先级有1-10级,数字越大优先级越高。但是优先级越高cpu也不一定优先调用。
  • 方法:
    获取线程优先级:getPriority()
    设置线程优先级:setPriority(int priority)
  • 实例:设置不同线程的优先级并查看调用结果。
public class TestPriority implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "------>" + Thread.currentThread().getPriority());
    }

    public static void main(String[] args) {
        TestPriority testPriority = new TestPriority();
        Thread thread1 = new Thread(testPriority);
        Thread thread2 = new Thread(testPriority);
        Thread thread3 = new Thread(testPriority);
        Thread thread4 = new Thread(testPriority);
        
        // 先设置优先级再启动
        thread1.setPriority(3);
        thread1.start();

        thread2.setPriority(Thread.MAX_PRIORITY);
        thread2.start();

        thread3.setPriority(7);
        thread3.start();

        thread4.setPriority(2);
        thread4.start();
    }
}

七、守护线程

  • 内容:线程分为用户线程和守护线程。用户线程(main())虚拟机需要等它执行完毕后再停止,守护线程(gc())虚拟机无需等它执行完毕再停止。守护线程可用于后台记录操作的日志、监控内存、垃圾回收等待时。
  • 方法:线程**调用setDaemon(true)**方法。默认为false为用户线程。
  • 实例:依照视频中例子,模拟人类(用户线程)的生命有限,而上帝(守护线程)可以无限守护。当用户线程完成停止时,虚拟机停止,守护线程也无法继续进行。
public class TestDaemon {
    public static void main(String[] args) {
        God god = new God();
        Thread thread = new Thread(god);
        thread.setDaemon(true);
        thread.start();

        You you = new You();
        new Thread(you).start();
    }
}

class God implements Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("上帝守护着你");
        }

    }
}

class You implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 30000; i++) {
            System.out.println("你度过了第" + i + "天");
        }
        System.out.println("say goodbye");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值