java多线程: 线程状态

线程状态(五大状态)

  • void setPriority(int newPriority) 更改线程的优先级。

  • static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。

  • void join() 等待该线程终止。

  • static void yield() 暂停当前正在执行的线程对象,并执行其他线程。

  • void interrupt() 中断线程。 (别用这个方式)

  • boolean isAlive() 测试线程是否处于活动状态。

线程停止

  • 不推荐使用jdk提供的stop()、destroy()方法

  • 推荐线程自己停下来

  • 建议使用一个标志位进行终止变量,当flag=false时终止线程运行

    //测试stop
    //1.建议线程正常停止-->利用次数,不建议死循环
    //2.建议使用标志位-->设置一个标志位
    //3.不要使用stop或destroy等过时或者jdk不建议使用的方法
    public class TestStop 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) {
            TestStop testStop = new TestStop();
            new Thread(testStop).start();
            for (int i = 0; i < 800; i++) {
                System.out.println("main"+i);
                if (i == 500) {
                    testStop.stop();
                    System.out.println("线程该停止了" +
                            "");
                }
            }
        }
    }
    

线程休眠

  • sleep(时间)指定当前线程阻塞的毫秒数

  • sleep存在异常InterruptedException

  • sleep时间达到后线程进入就绪状态

  • sleep可以模拟网络延时,倒计时

  • 每一个对象都有一个锁,sleep不会释放锁

  • 模拟网络延时的作用:放大问题的发生性(比如之前的抢火车票多线程问题)

    //打印当前系统时间
    Date startTime = new Date(System.currentTimeMillis());//获取系统当前时间
    while (true) {
        try {
            Thread.sleep(1000);
            System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
            startTime = new Date(System.currentTimeMillis());//更新当前时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    

线程礼让

  • 让当前正在执行的线程暂停,但不阻塞

  • 将线程从运行状态转为就绪状态

  • 让cpu重新调度,礼让不一定成功


线程强制执行

  • Join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞

  • 可以想象成插队

    public class TestJoin implements Runnable{
        public static void main(String[] args) {
            TestJoin testJoin = new TestJoin();
            Thread thread = new Thread(testJoin);
            thread.start();
    
            //主线程
            for (int i = 0; i < 500; i++) {
                System.out.println("main"+i);
                if (i == 100) {
                    try {
                        thread.join();//插队
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 500; i++) {
                System.out.println("线程vip来了"+i);
            }
        }
    }
    

线程状态观测

  • Thread.State线程状态。

  • 线程可以处于下列状态之一:

    • NEW :至今尚未启动的线程处于这种状态。
    • RUNNABLE:正在 Java 虚拟机中执行的线程处于这种状态。
    • BLOCKED :受阻塞并等待某个监视器锁的线程处于这种状态。
    • WAITING :无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。
    • TIMED_WAITING :等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。
    • TERMINATED已退出的线程处于这种状态。
  • 在给定时间点上,一个线程只能处于一种状态。这些状态是虚拟机状态,它们并没有反映所有操作系统线程状态。

    public class TestState {
        public static void main(String[] args) throws InterruptedException {
            Thread thread = new Thread(()->{
                for (int i = 0; i < 5; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("/////////////////");
            });
            //观察状态
            Thread.State state = thread.getState();
            System.out.println(state);//NEW
    
            thread.start();
            state = thread.getState();
            System.out.println(state);//RUNNABLE
    
            while (state!= Thread.State.TERMINATED) {//只要线程不终止就一直输出状态
                Thread.sleep(100);
                state = thread.getState();
                System.out.println(state);//TERMINATED
            }
        }
    }
    
    

线程的优先级

  • Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有的线程,线程调度器按照优先级决定应该调度哪个线程来执行

  • 线程的优先级用数组表示(1~10):

    • Thread.MIN_PRIORITY =1
    • Thread.MAX_PRIORITY =10
    • Thread.NORM_PRIORITY =5
  • 使用以下方式改变或获取优先级

    • int getPriority():返回线程的优先级。
    • void setPriority(int newPriority) :更改线程的优先级。
  • 优先级低只是意味着获得调度的概率低,并不是优先级低就不会被调用了,这都是看CPU的调度

    public class TestPriority{
        public static void main(String[] args) {
            //打印主线程的优先级(默认的)
            System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
            MyPriority myPriority = new MyPriority();
            Thread t1 = new Thread(myPriority);
            Thread t2 = new Thread(myPriority);
            Thread t3 = new Thread(myPriority);
            Thread t4 = new Thread(myPriority);
            Thread t5 = new Thread(myPriority);
            //先设置优先级再启动
            t1.start();
    
            t2.setPriority(4);
            t2.start();
    
            t3.setPriority(Thread.MAX_PRIORITY);
            t3.start();
        }
    }
    
    class MyPriority implements Runnable {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
        }
    }
    //main-->5
    //Thread-0-->5
    //Thread-2-->10
    //Thread-1-->4
    

守护(daemon)线程

  • 线程分为用户线程守护线程

  • 虚拟机必须确保用户线程执行完毕

  • 虚拟机不用等待守护线程执行完毕

  • 如:后台记录操作日志,监控内存,垃圾回收等待……

  • void setDaemon(boolean on) :将该线程标记为守护线程或用户线程。

    public class TestDaemon {
        public static void main(String[] args) {
            God god = new God();
            You you = new You();
            Thread thread = new Thread(god);
            thread.setDaemon(true);//默认时false表示是用户线程
            thread.start();
            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 < 36500; i++) {
                System.out.println("你一生都开心地活着");
            }
            System.out.println("========goodbye!world!========");
        }
    }
    
posted @ 2021-01-21 22:30  迪迦是真的  阅读(124)  评论(0)    收藏  举报
//复制代码按钮 //代码行号 //评论