JavaSE进阶(二)——多线程详解
前言
本篇笔记记录线程的各种状态以及状态的实际含义。
线程状态
线程分为五大状态(以前有三个状态,但是不足以描述线程的各种情况),具体如图:
- 运行:对活跃就绪的进程分配CPU资源后,则开始进入运行状态;‘
- 静止就绪:人为的从运行状态将进程挂起,使其进程不再执行;
- 活跃就绪:人为的从静止就绪状态将进程激活,是其进程继续执行;
- 静止阻塞:人为的将活跃阻塞的进程挂起。
- 活跃阻塞:除CPU资源外,其他资源也没有分配成功,则会进入活跃阻塞。
以上内容不在Java篇做赘述,需要了解的同学可以查看以下链接:
线程各种状态的方法
【注】:我们建议线程正常停止,利用循环或者递归出口,除特殊情况外不建议死循环;同时不建议使用过时或者不建议使用的方法。
stop:线程停止
我们一般采用在外部(主线程)设置状态为的方式来结束子线程。
sleep:线程休眠
该方法参数单位为毫秒(1secound = 1000millis)
sleep在使用的时候需要抛出一个异常InterruptedException;当休眠时间结束后,线程会进入就绪状态;
public class Demo1 implements Runnable {
private boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Demo1 d = new Demo1();
int i = 0;
new Thread(d).start();
// 设置外部状态位
while (true){
// 设置延时执行
Thread.sleep(1);
if (i > 10000){
d.stop();
break;
}
i ++;
}
}
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("run...Thread" + i ++);
}
}
public void stop(){
this.flag = false;
}
}
程序会在主线程走到结束位后将子线程停止,根据逻辑我们也可以设置为子线程结束后继续执行主线程。
线程就绪
将线程从运行状态变为就绪状态(看CPU心情来决定是否能修改成功)。
Thread.yield();
线程强制执行
通过join方式来强制执行线程,完成后再执行其他线程,否则其他线程阻塞。可以理解一种插队现象。
thread.join();
线程状态
线程的状态在Java中的显示:
- NEW:尚未启动的线程;
- RUNNABLE:正在运行的线程;
- BLOCKED:被阻塞等待监视器锁定的线程;
- WITING:正在等待另一个线程执行特定动作的线程;
- TIMED_WAITING:正在等待另一个线程执行动作达到制定等待时间的线程;
- TERMINATED:退出的线程
Thread.State state = thread.getState();
线程优先级
Java提供一个线程调度器来按照就绪状态的所有线程的优先级来执行调度,但是一般来说,主要执行线程的是CPU,所以优先级有用,但不完全有用。
有衔接一共分为十个,范围是1~10,这个在源码中可以看到相关设置:
上图中可以看到一般情况下,我们默认的线程优先级为5,同时可以手动设置线程的优先级。
在代码中设置了三个优先级常量,规定了线程优先级的最大值、最小值以及默认值,手动设置优先级的方法如下:
public class MyPriority implements Runnable{
@Override
public void run(){
}
}
public class Demo{
public static void main(String[] args){
MyPriority myPriority = new MyPriority();
Thread thread1 = new Thread(myPriority);
Thread thread2 = new Thread(myPriority);
Thread thread3 = new Thread(myPriority);
Thread thread4 = new Thread(myPriority);
thread1.setPriority(1);
thread2.setPriority(2);
thread3.setPriority(4);
thread4.setPriority(8);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
-
先设置优先级在启动;
-
设置的优先级从1开始,最高为10,不能超过范围;
-
原则上优先级高的会先执行,但并不是优先级低就不会调度,主要看CPU;
-
线程调度可以看操作系统概述。
守护线程(daemon)
线程共分为两种:用户线程和守护线程。在Java中,虚拟机必须确保用户线程执行完毕;不用等待守护线程执行完毕。守护线程一般都是在后台执行的,比如:操作日志、监控内存、垃圾回收等。
守护线程的设置方式:
// 默认为false,表示为用户线程;true表示守护线程
thread.setDaemon(true);
- 只要用户线程执行完毕,守护线程就会随之结束;
- 即使守护线程设置为死循环也无效,虚拟机不会在乎守护线程是否执行完毕。
总结
本篇笔记记录了线程的一些基础知识点,其中有很多是固定搭配。除了线程方面的相关逻辑问题,其余的代码逻辑性不强,大家靠记忆就可以了。
下一篇笔记会记录逻辑性比较强的线程同步,这是线程方面比较重要的阶段,大家一起努力。