目录

1.ID

2.名称

3.状态

4.优先级

5.是否守护线程

5.1.线程类型:

①用户线程(main线程默认是用户线程)

②守护线程(后台/系统线程)

5.2.守护线程作用

5.3.守护线程应用

5.4.守护线程使用

①在用户线程(main线程)中创建的子线程默认情况下也是用户线程

②在守护线程中创建的子线程默认情况下也是守护线程

③守护线程和用户线程的区别

6.是否存活

7.是否被中断

PS:线程执行顺序or随机判断准则



1.ID

是线程的唯⼀标识,不同线程ID不会重复,是动态分配的。(相当于进程PID)

2.名称

是各种调试⼯具⽤到,默认不同线程名称是不同的,但若手动指定不同线程名称可以重复。

/**
 * 线程属性:id、name
 */
public class ThreadDemo13 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                //得到执行当前任务的线程
                Thread t = Thread.currentThread();
                //打印线程id(是long类型)
                System.out.println("线程ID:" + t.getId());
                //打印线程名称
                System.out.println("线程名称:" + t.getName());
            }
        };

        Thread thread = new Thread(runnable,"线程1");
        thread.start();

        Thread.sleep(500);
        System.out.println();

        Thread thread2 = new Thread(runnable,"线程1");
        thread2.start();
    }
}

3.状态

表示线程当前所处的⼀个情况。

/**
 * 线程状态的流转
 */
public class ThreadDemoByState {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                //拿到当前线程,并打印当前线程的状态
                Thread thread = Thread.currentThread();
                System.out.println("线程状态2:" + thread.getState());
            }
        });
        //打印线程的状态
        System.out.println("线程状态:" + t.getState());
        t.start();

        //再次打印线程状态
        Thread.sleep(500);
        System.out.println("线程状态3:" + t.getState());
    }
}

java 分配 线程id java 线程id会重复吗_java

4.优先级

优先级⾼的线程理论上来说更容易被调度到。

线程创建之后,优先级就已经存在了。

/**
 * 获取线程优先级
 */
public class ThreadDemoByPriority {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //得到当前线程,并打印线程优先级
                Thread t = Thread.currentThread();
                System.out.println("线程优先级:" + t.getPriority());
            }
        });
        System.out.println("线程优先级2:" + thread.getPriority());
        thread.start();
        Thread.sleep(500);
        System.out.println("线程优先级3:" + thread.getPriority());
    }
}

java 分配 线程id java 线程id会重复吗_java_02

线程优先级是int类型值,为1-10,最小优先级是1,最高优先级是10,默认优先级是5。

java 分配 线程id java 线程id会重复吗_System_03

设置线程优先级(2种):

t1.setPriority(Thread.MAX_PRIORITY);
t1.setPriority(10);
/**
 * 设置线程优先级
 */
public class ThreadDemoByPriority2 {
    private final static int MAX_COUNT = 7;
    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //得到当前线程
                Thread t = Thread.currentThread();
                //得到线程的优先级
                int priority = t.getPriority();
                for (int i = 0; i < MAX_COUNT; i++) {
                    System.out.println(t.getName() + "——优先级:" + priority);
                }
            }
        },"线程1");
        //设置线程优先级(2种写法)
//        t1.setPriority(10); //直接赋值
        t1.setPriority(Thread.MAX_PRIORITY); //枚举

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread t = Thread.currentThread();
                int priority = t.getPriority();
                for (int i = 0; i < MAX_COUNT; i++) {
                    System.out.println(t.getName() + "——优先级:" + priority);
                }
            }
        },"线程2");
        t2.setPriority(Thread.MIN_PRIORITY);

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                Thread t = Thread.currentThread();
                int priority = t.getPriority();
                for (int i = 0; i < MAX_COUNT; i++) {
                    System.out.println(t.getName() + "——优先级:" + priority);
                }
            }
        },"线程3");
        t3.setPriority(Thread.NORM_PRIORITY);

        //同时启动线程(非常快,可以认为是同时的)
        t2.start();
        t1.start();
        t3.start();
    }
}

java 分配 线程id java 线程id会重复吗_用户线程_04

多个线程设置了不同的优先级,同时启动这多个线程,并不是优先级最高的一定先执行完之后再执行优先级最低的线程,而是高优先级获取到CPU时间片的概率更多,整个执行大致符合高优先级的线程最先执行完。

快捷键设置:

ctrl+F查找

ctrl+H替换

java 分配 线程id java 线程id会重复吗_System_05

5.是否守护线程

5.1.线程类型:

①用户线程(main线程默认是用户线程)

程序员创建的线程。

②守护线程(后台/系统线程)

5.2.守护线程作用

守护线程是为⽤户线程服务的,当一个程序中的所有⽤户线程全部结束之后,守护线程会跟随结束。

5.3.守护线程应用

JVM 中的垃圾回收器就是典型的守护线程,程序运⾏的时候它也运⾏,当满⾜条件时进⾏垃圾回收,在一个进程中所有非后台线程执⾏完任务终⽌时它才会结束运行。

5.4.守护线程使用

//获取当前线程是否是守护线程
thread.isDaemon()
//true->守护线程; false->用户线程
//手动指定线程类型
t1.setDaemon(true);
//true->守护线程; false->用户线程

①在用户线程(main线程)中创建的子线程默认情况下也是用户线程

/**
 * 守护线程示例
 */
public class ThreadDemoByDaemon {
    public static void main(String[] args) throws InterruptedException {
        //得到当前的线程(main主线程)
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "——是否是守护线程:" + thread.isDaemon());

        Thread t1 = new Thread(() -> {
            //得到当前线程
            Thread cThread = Thread.currentThread();
            System.out.println(cThread.getName() + "——是否是守护线程:" + cThread.isDaemon());
        },"子线程1");
        t1.start(); //启动线程
    }
}

通过这个示例可得出结论:

  1. main线程(主线程)默认是用户线程(非守护线程)。
  2. 在用户线程中创建的子线程也是用户线程。

②在守护线程中创建的子线程默认情况下也是守护线程

/**
 * 守护线程示例
 */
public class ThreadDemoByDaemon {
    public static void main(String[] args) throws InterruptedException {
        //得到当前的线程(main主线程/用户线程)
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "——是否是守护线程:" + thread.isDaemon());

        Thread t1 = new Thread(() -> {
            //得到当前线程t1
            Thread cThread = Thread.currentThread();
            System.out.println(cThread.getName() + "——是否是守护线程:" + cThread.isDaemon());

            //创建子线程tt1
            Thread tt1 = new Thread(() -> {
                Thread cThread2 = Thread.currentThread();
                System.out.println(cThread2.getName() + "——是否是守护线程:" + cThread2.isDaemon());
            },"子线程t1的子线程tt1");
            tt1.start();

        },"子线程t1");

        //手动指定线程t1为守护线程
        t1.setDaemon(true);
        t1.start(); //启动线程

        //主线程休眠1s
        Thread.sleep(1000);
    }
}

java 分配 线程id java 线程id会重复吗_java_06

注:线程类型(用户or守护)不能在线程运行期间,也就是调用了 start() 之后设置,否则JVM会报错。

③守护线程和用户线程的区别

/**
 * 对比用户线程和守护线程的区别
 */
public class ThreadDemoByDaemon2 {
    public static void main(String[] args) throws InterruptedException {
        userThread();
        daemonThread();
    }

    /**
     * 用户线程
     */
    private static void userThread() {
        Thread thread = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("用户线程执行:" + i);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }

    /**
     * 守护线程
     */
    private static void daemonThread() {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("守护线程执行:" + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //设置为守护线程
        t.setDaemon(true);
        //启动线程
        t.start();
    }
}

java 分配 线程id java 线程id会重复吗_java 分配 线程id_07

结论:JVM会等待所有的用户线程执行完再自然退出,但JVM不会等待守护线程执行完再退出。若用户线程没执行完强制退出,JVM也会退出。

线程的类型和线程的调度无关,只有线程的优先级和线程的调度有关。

6.是否存活

简单的理解为 run ⽅法是否运⾏结束了。

public class ThreadDemoByAlive {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
           Thread thread = Thread.currentThread();
            System.out.println("线程是否存活2:" + thread.isAlive());
        });
        System.out.println("线程是否存活:" + t.isAlive());
        t.start();
        System.out.println("线程是否存活3:" + t.isAlive());
        Thread.sleep(1000);
        System.out.println("线程是否存活4:" + t.isAlive());
    }
}

使用场景:

public class ThreadDemoByAlive {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("1:线程执行完了!");
        });
        t.start();
        while(t.isAlive()){
        }
        System.out.println("2:确认线程执行完了!");
    }
}

7.是否被中断

线程在休眠或执行当中,其他线程可以操作此线程让其中断。

PS:线程执行顺序or随机判断准则

  1. 在一个线程里的执行顺序是从上往下的。
  2. 多个线程之间的执行是随机的,因为线程调度是随机的。
public class ThreadDemo13 {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                //得到执行当前任务的线程
                Thread t = Thread.currentThread();
                //打印线程id(是long类型)
                System.out.println(t.getName() + "——线程ID:" + t.getId());//①
                //打印线程名称
                System.out.println(t.getName() + "——线程名称:" + t.getName());//②
                //打印线程优先级
                System.out.println(t.getName() + "——线程优先级:" + t.getPriority());//③
            }
        };

        Thread thread = new Thread(runnable,"线程1");
        thread.start();

        Thread thread2 = new Thread(runnable,"线程2");
        thread2.start();

        Thread thread3 = new Thread(runnable,"线程3");
        thread3.start();
    }
}

java 分配 线程id java 线程id会重复吗_守护线程_08