Java多線程3:Thread中的靜態方法

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

相關文章
相關標籤/搜索