上一篇文章我们讲了Java关于线程的基本知识和如何创建一个简单的线程。Java使用Thread类来创建线程。多线程编程对于以前没有相关经验的人来说,最难理解的地方在于操作系统调度的执行过程。对于这样的代码:
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("thread");
});
thread.start();
System.out.println("main");
}
我们知道,java在启动的时候,已经自动创建了主线程,主线程调用main方法,main方法中又创建了一个线程(命名为”thread线程“),这个线程的任务是打印”thread“,同时,main方法中在创建一个新线程后的任务是打印”main“。当创建了thread线程并且start后,主线程和thread线程就是广泛上定义的并发(并发+并行)的过程,这个时候先打印”main“还是先打印”thread“是不确定的,是随机的,要看操作系统的随机调度。 同样着,谁先结束也是不确定的,也可能是主线程先结束,也可能是thread线程先结束。所以,为了让主线程等待thread线程结束,需要使用join方法。
创建线程是看start的顺序,但是具体的线程对应的任务什么时候执行,要看系统调度器。
Thread常见构造方法
比如使用lambda表达式创建一个线程并且起名字。线程在操作系统内部是没有名字的,只有一个身份标志。但是在java中为了更加明白线程是谁,在jvm中给对应的Thread对象加了一个和内核中线程一一对应关系的名字,就像姓名和身份证号之间的关系。这个名字对于程序的执行没有关系。如果不手动创建,也会有默认的名字。
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("thread");
}, "thread线程");
}
Thread常见的几个属性
ID表示线程的身份。ID有好几个,这里的方法获取到的是线程在JVM中的身份标识。线程的标识有好几个,在内核的PCB上有标识,在用户态线程库中也有标识(操作系统系统的线程库)。
getName()方法是获取到在Thread构造方法中传入的名字。
getState()方法是一个比较关键的属性。在PCB里面有几个状态,在这里得到的状态是JVM设定的状态,比操作系统内置的状态更加丰富。
isDaemon()方法,daemon称为”守护线程“,也可以称为后台线程。比如手机上的app,打开app,这个app就来到前台,当我们切换应用的时候,这个app就到后台了。线程也分成前台线程和后台线程,也可以设置线程的前后台。