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的中斷機制,留在後面的一篇文章專門講解。