Thread类中的静态方法异步
Thread类中的静态方法表示操做的线程是"正在执行静态方法所在的代码块的线程"。为何Thread类中要有静态方法,这样就能对CPU当前正在运行的线程进行操做。下面来看一下Thread类中的静态方法:测试
一、currentThread()this
currentThread()方法返回的是对当前正在执行线程对象的引用。看一个重要的例子,而后得出结论:spa
public class MyThread04 extends Thread { static { System.out.println("静态块的打印:" + Thread.currentThread().getName()); } public MyThread04() { System.out.println("构造方法的打印:" + Thread.currentThread().getName()); } public void run() { System.out.println("run()方法的打印:" + Thread.currentThread().getName()); } }
public static void main(String[] args) { MyThread04 mt = new MyThread04(); mt.start(); }
看一下运行结果:线程
静态块的打印:main 构造方法的打印:main run()方法的打印:Thread-0
这个例子说明了,线程类的构造方法、静态块是被main线程调用的,而线程类的run()方法才是应用线程本身调用的。在这个例子的基础上,再深刻:code
public class MyThread05 extends Thread { public MyThread05() { System.out.println("MyThread5----->Begin"); System.out.println("Thread.currentThread().getName()----->" + Thread.currentThread().getName()); System.out.println("this.getName()----->" + this.getName()); System.out.println("MyThread5----->end"); } public void run() { System.out.println("run----->Begin"); System.out.println("Thread.currentThread().getName()----->" + Thread.currentThread().getName()); System.out.println("this.getName()----->" + this.getName()); System.out.println("run----->end"); } }
public static void main(String[] args) { MyThread05 mt5 = new MyThread05(); mt5.start(); }
看一下运行结果:对象
MyThread5----->Begin Thread.currentThread().getName()----->main this.getName()----->Thread-0 MyThread5----->end run----->Begin Thread.currentThread().getName()----->Thread-0 this.getName()----->Thread-0 run----->end
上篇文章的开头就说过,要理解一个重要的概念,就是"this.XXX()"和"Thread.currentThread().XXX()"的区别,这个就是最好的例子。必需要清楚的一点就是:当前执行的Thread未必就是Thread自己。从这个例子就能看出来:blog
(1)执行MyThread05构造方法是main,当前线程倒是Thread-0资源
(2)执行run()方法的Thread-0,当前线程也是Thread-0,说明run()方法就是被线程实例去执行的get
因此,再强调一下,未必在MyThread05里调用Thread.currentThread()返回回来的线程对象的引用就是MyThread05
二、sleep(long millis)
sleep(long millis)方法的做用是在指定的毫秒内让当前"正在执行的线程"休眠(暂停执行)。这个"正在执行的线程"是关键,指的是Thread.currentThread()返回的线程。根据JDK API的说法,"该线程不丢失任何监视器的所属权",简单说就是sleep代码上下文若是被加锁了,锁依然在,可是CPU资源会让出给其余线程。看一下例子:
public class MyThread07 extends Thread { public void run() { try { System.out.println("run threadName = " + this.getName() + " begin"); Thread.sleep(2000); System.out.println("run threadName = " + this.getName() + " end"); } catch (InterruptedException e) { e.printStackTrace(); } } }
public static void main(String[] args) { MyThread07 mt = new MyThread07(); System.out.println("begin = " + System.currentTimeMillis()); mt.start(); System.out.println("end = " + System.currentTimeMillis()); }
看一下运行结果:
begin = 1443694780609 end = 1443694780609 run threadName = Thread-0 begin run threadName = Thread-0 end
固然,由于打印结果是静态的,因此只能看出异步执行的效果,看不出sleep(long millis)方法执行的效果。实际上第3句打出2秒后打出第4句,这和run()方法里面的sleep(2000)是对应的
三、yield()
暂停当前执行的线程对象,并执行其余线程。这个暂停是会放弃CPU资源的,而且放弃CPU的时间不肯定,有可能刚放弃,就得到CPU资源了,也有可能放弃好一下子,才会被CPU执行。看一下例子:
public class MyThread08 extends Thread { public void run() { long beginTime = System.currentTimeMillis(); int count = 0; for (int i = 0; i < 50000000; i++) { Thread.yield(); count = count + i + 1; } long endTime = System.currentTimeMillis(); System.out.println("用时:" + (endTime - beginTime) + "毫秒!"); } }
public static void main(String[] args) { MyThread08 mt = new MyThread08(); mt.start(); }
看一下运行结果:
用时:3264毫秒!
用时:3299毫秒!
用时:3232毫秒!
用时:3256毫秒!
用时:3283毫秒!
用时:3504毫秒!
用时:3378毫秒!
看到,每次执行的用时都不同,证实了yield()方法放弃CPU的时间并不肯定。
四、interrupted()
测试当前线程是否已经中断,执行后具备将状态标识清除为false的功能。换句话说,若是连续两次调用该方法,那么返回的一定是false:
public static void main(String[] args) { Thread.currentThread().interrupt(); System.out.println("是否中止1?" + Thread.interrupted()); System.out.println("是否中止2?" + Thread.interrupted()); System.out.println("end!"); }
固然,这也涉及Java的中断机制,留在后面的一篇文章专门讲解。