上QQ阅读APP看书,第一时间看更新
1.2.3 线程随机性的展现
前面介绍过线程的调用是随机的,但并没有从代码中体现出来,都是理论的讲解,所以本节将在名称为randomThread的Java项目中演示线程的随机特性。
图1-11 命令jvisualvm.exe的主界面
图1-12 可以看到5个线程
创建自定义线程类MyThread.java代码如下:
package mythread; public class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 10000; i++) { System.out.println("run=" + Thread.currentThread().getName()); } } }
再创建运行类Test.java代码如下:
package test; import mythread.MyThread; public class Test { public static void main(String[] args) { MyThread thread = new MyThread(); thread.setName("myThread"); thread.start(); for (int i = 0; i < 10000; i++) { System.out.println("main=" + Thread.currentThread().getName()); } } }
Thread.java类中的start()方法通知“线程规划器”——此线程已经准备就绪,准备调用线程对象的run()方法。这个过程其实就是让操作系统安排一个时间来调用Thread中的run()方法执行具体的任务,具有异步随机顺序执行的效果,如图1-13所示。
图1-13 随机被执行的线程
多线程随机输出的原因是CPU将时间片分给不同的线程,线程获得时间片后就执行任务,所以这些线程在交替执行并输出,导致输出结果呈乱序。
时间片即CPU分配给各个程序的时间。每个线程被分配一个时间片,在当前的时间片内执行线程中的任务。需要注意的是,当CPU在不同的线程上进行切换时是需要耗时的,所以并不是创建的线程越多,软件运行效率就越快,相反,线程数过多反而会降低软件的执行效率。
如果调用代码“thread.run();”而不是“thread.start();”,其实就不是异步执行了,而是同步执行,那么此线程对象并不交给线程规划器来进行处理,而是由main线程来调用run()方法,也就是必须等run()方法中的代码执行完毕后才可以执行后面的代码。