线程中常用的几个方法:currentThread()方法、isAlive()方法、sleep()方法、getId()方法和yield()方法。
currentThread()方法
1)currentThread()方法可返回代码段正在被哪个线程调用的信息。如代码清单1所示。
代码清单1 返回线程调用信息
运行结果如图1所示,构造方法被mian线程调用,而run方法被名称为Thread-0的线程调用。
图1 调用start()返回线程结果
当注释掉start()方法,启用myCurrentThread.run();
运行结果如图2所示。
图2 直接调用run()返回线程结果
2)在比较复杂的情况下,对currentThread()应用,如代码清单2所示。
代码清单2 复杂的情况下currentThread()应用
输出结果如图3所示。
图3 返回结果
在自定义线程类时,如果线程类是继承java.lang.Thread的话,那么线程类就可以使用this关键字去调用继承自父类Thread的方法,this就是当前的对象。
另一方面,Thread.currentThread()可以获取当前线程的引用,一般都是在没有线程对象又需要获得线程信息时通过Thread.currentThread()获取当前代码段所在线程的引用。
至于这里为什么两次this.getName都是Thread-0,因为this代表的是CountOpera这个对象,this.getName()其实就是最简单的方法调用,然而当前对象里面没有这个方法,又因为继承了Thread方法,所以它执行的就是Thread父类的方法,父类方法如下:
Thread-0就是上面init()方法将name的值设置进去。
isAlive()方法
1)方法isAlive()的功能是判断当前的线程是否处于活动状态。
代码清单3 isAlive()应用
运行结果如图4所示,"end=="+myIsAlive.isAlive()
的运行结果是true,但此值是不确定的。打印true值是因为myIsAlive线程还没有执行完毕,所以输出为true。
图4 返回结果
去掉代码中注释,开启sleep()方法,运行结果如图5所示。"end=="+myIsAlive.isAlive()
输出的结果为false,因为myIsAlive对象已经在1秒之内执行完毕。
图5 开启sleep()返回结果
2)在使用isAlive()方法时,如果将线程对象以构造参数的方式传递给Thread对象进行start()启动时,运行的结果和前面示例是有差异的。造成这样的差异的原因还是来之于Thread.currentThread()和this的差异。
代码清单4 测试一下上面结果
尽管this与Thread.currentThread() 都可以获取到Thread的引用,但是在某种情况下获取到的引用是有差别的。
图6 运行结果
sleep()方法
1)方法sleep()的作用是在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)。这个“正在执行的线程”是指this.currentThread()返回的线程。
代码清单5 sleep()休眠线程
直接调用run()方法,运行结果如图7所示。
图7 直接调用run()方法
2)使用start()启动线程。
代码清单6 start()启动线程
由于mian线程与t线程时异步执行的,所以首先打印的信息为begin和end。而t线程时随后运行的,在最后两行打印run begin 和run end相关的信息。
图8 用start()启动线程
getId()方法
getId()方法的作用是取得线程的唯一标识。
代码清单7 获取id值
从运行结果看线程名为mian,id为1.
图9 获取id
yield()方法
yield()方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片。
代码清单8 取得运行时间,测试yield方法的使用效果
运行结果如题10 所示。
图10 CPU独占时间
去掉//Thread.yield();
注释,再次运行,如图11所示。
图11 将CPU让给其他资源导致速度变慢