Java多线程-线程状态、优先级

线程状态

线程从开启到结束运行,都有它自己的状态。Thread类中有一个枚举类可以表示所有的状态。我们也把它们大致分成这几个状态:

  1. 新建,线程刚new出来的时候
  2. 就绪,线程调用 start()
  3. 运行,cpu执行线程
  4. 阻塞运行中的线程因为某些操作中断运行,比如调用 sleep() 方法,阻塞完成后会回到就绪状态
  5. 终止,线程的 run() 方法执行完毕

Thread的枚举类State

  1. NEW,线程刚创建的状态
  2. RUNNABLE,运行中的线程
  3. BLOCKED,线程被阻塞的状态
  4. WAITING,等待执行的线程
  5. TIMED WAITING,等待sleep结束的线程
  6. TERMINATED,执行完毕的线程

停止线程

不推荐直接调用线程的 stop() 方法来停止线程。

可以自己写一个boolean标记来完成线程的停止:

package thread.situation;

public class StopDemo implements Runnable{
    private boolean flag=true;
    private int i=0;
    @Override
    public void run()
    {
        while(flag)
        {
            System.out.println("子线程执行中..."+i++);
        }
    }
    public void stop()
    {
        flag = false;
    }

    //主方法
    public static void main(String[] args) {
        StopDemo s = new StopDemo();
        Thread t = new Thread(s);
        t.start();
        for (int i = 0; i < 100000000 ; i++)
        {
            System.out.println("Main Thread has execute"+i);
            if(i==9000000)
            {
                s.stop();
                System.out.println("Make the subthread stop...");
            }
        }
    }
}

线程的几种方法:

  • sleep(100) 让线程阻塞100毫秒,阻塞后回到就绪状态
  • yield() 运行中让线程回到就绪状态,重新等待 cpu 的调用
  • join() 让线程插队执行,插队执行的时候其它线程都会进入阻塞状态,少用。

线程优先级

前面已经说过,调用就绪状态的线程是由CPU内部决定的,我们干预不了。但有时候,我们想让某个线程优先执行怎么办呢?我们可以向CPU提建议,也就是设置线程的优先级

Thread 类中使用[1,10]来表示线程的优先级。它还内置了3个优先级常量:MIN_PRIORITYNORM_PRIORITYMAX_PRIORITY,实际值分别是1,5,10。

我们可以在线程 start()调用它的 setPriority(int x) 方法设置优先级来向CPU建议最好先执行哪个线程(当然CPU听不听就不知道了)。

使用 getPriority()方法可以查看当前线程的优先级。

package thread.situation;

public class StopDemo implements Runnable{

    @Override
    public void run()
    {
        System.out.println(Thread.currentThread().getName()+"优先级是"+Thread.currentThread().getPriority());
    }
}
class Demo{
    public static void main(String[] args) throws InterruptedException {
        StopDemo s = new StopDemo();
        Thread t1 = new Thread(s,"最好的线程");
        Thread t2 = new Thread(s,"最差的线程");
        Thread t3 = new Thread(s,"有点好的线程");
        Thread t4 = new Thread(s,"有点差的线程");
        t1.setPriority(Thread.MAX_PRIORITY);
        t2.setPriority(Thread.MIN_PRIORITY);
        t3.setPriority(8);
        t4.setPriority(3);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        System.out.println("主线程的优先级是"+Thread.currentThread().getPriority());
    }
}

某次输出结果:

主线程的优先级是5
最差的线程优先级是1
有点差的线程优先级是3
最好的线程优先级是10
有点好的线程优先级是8

很明显,CPU不太愿意接受我们的建议。

守护线程

线程其实是有两种的。一种是用户线程,一种是守护线程(Daemon)。用户线程就是我们创建出来的线程,主线程也是用户线程的一种。守护线程主要是一些服务线程,比如监控内存、垃圾回收线程之类的。它们的区别在执行方式上。

  • 如果是用户线程,JVM会在所有的用户线程执行完后关机
  • 如果是服务线程...我都这么写了JVM会怎么对待守护线程不用我说了吧(即使有守护线程在运行,JVM还是会装作看不到然后关机)。

通过调用 Thread 类的 setDeamon() 方法并传入一个 true 就可以把该类变成守护线程了。

package thread.situation;

public class StopDemo implements Runnable{
    @Override
    public void run(){}
}
class Man implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("你"+i+"岁了");
        }
        System.out.println("////// ansl \\\\\\");
    }
}
class BigBrother implements Runnable{
    @Override
    public void run() {
        while(true) {
            for (int i = 0; i < 20000; i++)
            {
                System.out.println("Big Brother has watched you"+ i +"times");
            }

        }
    }
}
class Demo{
    public static void main(String[] args) throws InterruptedException {
        BigBrother bigBrother = new BigBrother();
        Man you = new Man();
        Thread brotherThread = new Thread(bigBrother);
        brotherThread.setDaemon(true);
        brotherThread.start();
        new Thread(you).start();
    }
}

最后一段输出结果:

你99岁了
Big Brother has watched you54times
////// ansl \\\
Big Brother has watched you55times
Big Brother has watched you56times
Big Brother has watched you57times
Big Brother has watched you58times
Big Brother has watched you59times
Big Brother has watched you60times
Big Brother has watched you61times
Big Brother has watched you62times
Big Brother has watched you63times
Big Brother has watched you64times
Big Brother has watched you65times
Big Brother has watched you66times
Big Brother has watched you67times
Big Brother has watched you68times

Big Brother的循环还没跑完,JVM就关机了。

你可能感兴趣的:(Java多线程-线程状态、优先级)