资深软件开发工程师,业余马拉松选手。
Java语言内置了多线程支持。当Java程序启动的时候,实际上是启动了一个JVM进程,然后,JVM启动主线程来执行方法。在方法中,我们又可以启动其他线程。
要创建一个新线程非常容易,我们需要实例化一个实例,然后调用它的方法:
但是这个线程启动后实际上什么也不做就立刻结束了。我们希望新线程能执行指定的代码,有以下几种方法:
方法一:从派生一个自定义类,然后覆写方法:
执行上述代码,注意到方法会在内部自动调用实例的方法。
方法二:创建实例时,传入一个实例:
或者用Java 8引入的lambda语法进一步简写为:
有童鞋会问,使用线程执行的打印语句,和直接在方法执行有区别吗?
区别大了去了。我们看以下代码:
我们用蓝色表示主线程,也就是线程,线程执行的代码有4行,首先打印,然后创建对象,紧接着调用启动新线程。当方法被调用时,JVM就创建了一个新线程,我们通过实例变量来表示这个新线程对象,并开始执行。
接着,线程继续执行打印语句,而线程在线程执行的同时会并发执行,打印和语句。
当方法结束时,新线程就结束了。而方法结束时,主线程也结束了。
我们再来看线程的执行顺序:
- 线程肯定是先打印,再打印;
- 线程肯定是先打印,再打印。
但是,除了可以肯定,会先打印外,打印在之前、之后或者之间,都无法确定。因为从线程开始运行以后,两个线程就开始同时运行了,并且由操作系统调度,程序本身无法确定线程的调度顺序。
要模拟并发执行的效果,我们可以在线程中调用,强迫当前线程暂停一段时间:
传入的参数是毫秒。调整暂停时间的大小,我们可以看到线程和线程执行的先后顺序。
要特别注意:直接调用实例的方法是无效的:
直接调用方法,相当于调用了一个普通的Java方法,当前线程并没有任何改变,也不会启动新线程。上述代码实际上是在方法内部又调用了方法,打印语句是在线程中执行的,没有任何新线程被创建。
必须调用实例的方法才能启动新线程,如果我们查看类的源代码,会看到方法内部调用了一个方法,修饰符表示这个方法是由JVM虚拟机内部的C代码实现的,不是由Java代码实现的。
可以对线程设定优先级,设定优先级的方法是:
JVM自动把1(低)~10(高)的优先级映射到操作系统实际优先级上(不同操作系统有不同的优先级数量)。优先级高的线程被操作系统调度的优先级较高,操作系统对高优先级线程可能调度更频繁,但我们决不能通过设置优先级来确保高优先级的线程一定会先执行。
创建一个新线程。
下载练习
Java用对象表示一个线程,通过调用启动一个新线程;
一个线程对象只能调用一次方法;
线程的执行代码写在方法中;
线程调度由操作系统决定,程序本身无法决定调度顺序;
可以把当前线程暂停一段时间。
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/3361.html