目录
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());
}
}
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());
}
}
线程优先级是int类型值,为1-10,最小优先级是1,最高优先级是10,默认优先级是5。
设置线程优先级(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();
}
}
多个线程设置了不同的优先级,同时启动这多个线程,并不是优先级最高的一定先执行完之后再执行优先级最低的线程,而是高优先级获取到CPU时间片的概率更多,整个执行大致符合高优先级的线程最先执行完。
快捷键设置:
ctrl+F查找
ctrl+H替换
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) {
//得到当前的线程(main主线程)
Thread thread = Thread.currentThread();
System.out.println("是否是守护线程:" + thread.isDaemon());
Thread t1 = new Thread(() -> {
//得到当前线程
Thread cThread = Thread.currentThread();
System.out.println(cThread.getName() + "——是否是守护线程:" + thread.isDaemon());
},"子线程1");
t1.start(); //启动线程
}
}
②在守护线程中创建的子线程默认情况下也是守护线程
/**
* 守护线程示例
*/
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());
//创建子线程
Thread tt1 = new Thread(() -> {
Thread cThread2 = Thread.currentThread();
System.out.println(cThread2.getName() + "——是否是守护线程:" + cThread2.isDaemon());
},"子线程的子线程1");
tt1.start();
},"子线程1");
//手动指定线程为守护线程
t1.setDaemon(true);
t1.start(); //启动线程
//主线程休眠1s
Thread.sleep(1000);
}
}
注:线程类型(用户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();
}
}
结论: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随机判断准则
- 在一个线程里的执行顺序是从上往下的。
- 多个线程之间的执行是随机的,因为线程调度是随机的。
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(); } }