线程的状态,优先级以及sleep,join等方法

线程状态

Thread.State

线程状态:

  • NEW:还未启动

  • RUNNABLE:正在JVM中运行,但是可能正在等待操作系统的其他资源

  • 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); // 总计5s
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("sleep over...");
            });
    
            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);
            }
        }
    }
    

线程优先级

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

线程的优先级有数字来表示,范围1~10。

  • Thread.MIN_PRIORITY = 1;
  • Thread.MAX_PRIORITY = 10;
  • Thread.NORM_PRIORITY = 5;

使用以下方式改变优先级:

getPriority().setPriority(int x)

示例代码:

public class TestPriority {

    public static void main(String[] args) {
        // 主线程的默认优先级
        System.out.println(Thread.currentThread().getName()+"的优先级为"+Thread.currentThread().getPriority());

        MyPriority p1 = new MyPriority();
        MyPriority p2 = new MyPriority();
        MyPriority p3 = new MyPriority();
        MyPriority p4 = new MyPriority();
        MyPriority p5 = new MyPriority();
        MyPriority p6 = new MyPriority();

        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(p1);
        Thread t3 = new Thread(p1);
        Thread t4 = new Thread(p1);
        Thread t5 = new Thread(p1);
        Thread t6 = new Thread(p1);

        // 先设置,再运行
        t1.start(); // 默认不设置

        t2.setPriority(2);
        t2.start();

        t3.setPriority(4);
        t3.start();

        t4.setPriority(Thread.MAX_PRIORITY); // 10
        t4.start();

        t5.setPriority(-1);
        t5.start();

        t6.setPriority(11);
        t6.start();
    }

}

class MyPriority implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"的优先级为"+Thread.currentThread().getPriority());
    }
}

运行截图:

守护(daemon)线程

在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 。

虚拟机必须确保用户线程执行完毕,如main。

虚拟机不用等待守护线程执行完毕,如jc(垃圾回收),后台记录操作日志,监控内存等。

示例代码:

public class TestDaemon {

    public static void main(String[] args) {
        God god = new God();
        Thread daemon = new Thread(god);

        daemon.setDaemon(true); // 默认为false表示是用户线程,正常的线程都是用户线程
        daemon.start(); // 守护线程开始运行

        new Thread(new 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 = 1; i <= 100; i++) {
            if (i==1) System.out.println("==你出生了==");
            System.out.println("这是你活的第"+i+"年...");
            if (i == 100) System.out.println("==再见了,世界==");
        }
    }
}

注意:you结束后,守护线程还会运行一会是因为虚拟机关闭守护线程需要时间。

注意:优先级高的不一定先执行,但是大概率先执行。

停止线程

在java中有三种方法可以停止线程,推荐线程自己停下来

  1. 使用退出标志,让线程正常退出,也就是当run方法执行完之后终止
  2. 使用stop方法强制终止线程,但是不推荐使用,因为stop和suspend及resume一样,是java废弃的方法
  3. 使用interrupt方法中断线程

示例代码:使用标志位使线程停止,main和Thread交替进行

public class TestStop implements Runnable {

    private boolean flag = false;

    public static void main(String[] args) {
        TestStop stop = new TestStop();
        new Thread(stop).start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("main i:"+i);
            if (i==300) {
                stop.changeStop();
                System.out.println("线程停止了...");
            }
        }
    }

    public void changeStop() {
        this.flag = !this.flag;
    }

    @Override
    public void run() {
        int i = 0;
        while (!flag) {
            System.out.println("Thread run "+i+++"...");
        }
    }
}

sleep

sleep(int millsecond): 优先级高的线程可以在它的run()方法中调用sleep方法来使自己放弃CPU资源,休眠一段时间。

作用:放大问题的发生性

示例代码:模拟倒计时

public static void main(String[] args) {
    try {
        daoJiShi();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
// 模拟倒计时
public static void daoJiShi() throws InterruptedException {
    int num = 10;
    while (num>-1) {
        System.out.println(num--);
        Thread.sleep(1000); // 1秒
    }
}

yield

礼让进程,让 当前正在执行的进程暂停,但不阻塞。

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

让cpu重新调度,礼让不一定成功!看cpu心情

实例代码:

public class TestYield {

    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() {
        String name = Thread.currentThread().getName();
        System.out.println(name+"开始执行...");
        Thread.yield(); //礼让
        System.out.println(name+"结束执行...");
    }
}

运行截图:

礼让成功截图:

礼让失败截图:

join

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

实例代码:

public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("VIP 来了 i:"+i+"...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestJoin join = new TestJoin();
        Thread thread = new Thread(join);
        thread.start();

        // 主线程
        for (int i = 0; i < 200; i++) {
            if (i==120)
                thread.join(); // 插队
            System.out.println("in main "+i+"...");
        }
    }
}

引用资料

【狂神说Java】多线程详解

Java——多线程之方法详解

Java线程常用方法详解

posted @ 2022-02-26 14:13  zzzzzzsl  阅读(113)  评论(0)    收藏  举报