一文搞懂Thread類核心用法

簡介

直奔主題,從源碼解析Thread的用法以及多線程的使用

public class Thread
extends Object
implements Runnable
// Runnable接口定
public interface Runnable {

    public abstract void run();
}

//Thread重寫run方法
  @Override
    public void run() {
        if (target != null) {
        //private Runnable target;最終調Runable接口實現類的run方法
            target.run();
        }
    }


構造方法解析

 /**
     *分配新的線程對象。此構造函數與Thread(null、null、gname)具有相同的效果,
     *其中gname是線程名稱。自動生成的名稱的格式爲“Thread-”+n,其中n是整數。
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }
o
//這裏交代可以用子類繼承Thread,即Thread t=new SonThread();並重寫Thread的run方法,調用start方法開啓線程



 /**
     * 分配新的線程對象。此構造函數與Thread(null、target、gname)具有相同的效果,其中
     * gname是新生成的名稱。自動生成的名稱的格式爲“Thread-”+n,其中n是整數。
     *
     * @param  target Runable接口實例
     *       
     */
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }


//這裏交代可以用Runable接口實例作爲參數給Threa,Runable接口實例實現run方法,

從構造方法可以看出實現線程的方式只有一種,那就是new一個Threa類出來,只是run方法來源不同,一個實現Runable接口run方法,一個是重寫Thrad的run方法,但是無論如何Runable接口都是實現線程的頂層接口,除此之外表面上線程池、定時器等工具類也可以創建線程,但是底層都是通過new Thread類來實先線程,官方java語言規範明確記載new Threa()是實現線程的唯一方法。

在博客多線程編程知識點一有詳細介紹如何創建多線程

重要方法



 /**
     * 返回對當前正在執行的線程對象的引用。
     *
     * @return  the currently executing thread.
     */
    @FastNative
    public static native Thread currentThread();


/**
     * 返回當前線程的名稱
     *
     * @return  this thread's name.
     * @see     #setName(String)
     */
    public final String getName() {
        return name;
    }
通常的用法是 Thread.currentThread().getName()


/**
     * 
     * 是線程休眠指定時間,但是不釋放鎖的控制權,時間到了甦醒繼續試圖獲取CPU執行權
     *
     * @param 參數爲一個毫秒值
     *
     * @throws  IllegalArgumentException
     *          如果參數爲負數
     *
     * @throws  InterruptedException
     *          如果有線程中斷了當前線程。引發此異常時,當前線程的中斷狀態將被清除。
     */
    public static void sleep(long millis) throws InterruptedException {
        Thread.sleep(millis, 0);
    }

 
/**
     * 
     *
     *通常在其他線程調用此方法。來中斷線程
     *
     *如果此線程在調用對象類的wait()、wait(long)或wait(long,int)方法
     *或該類的join()、join(long)、join(long,int)、sleep(long)或
     *sleep(long,int)方法時被阻止,則其中斷狀態將被清除,並將接收到InterruptedException。
     *
     *
     * 此外將設置中斷狀態
     * 中斷不活動的線程沒有任何效果
     *
     * @throws  SecurityException
     *         自己中斷自己,如果當前線程無法修改此線程
     *
     * @revised 6.0
     * @spec JSR-51
     */
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                nativeInterrupt();
                b.interrupt(this);
                return;
            }
        }
        nativeInterrupt();
    }


 /**
     * T測試線程是否被中斷,不會清除中斷狀態
     *
     *中斷返回true,否則返回false
     *
     * @see     #interrupted()
     * @revised 6.0
     */
    @FastNative
    public native boolean isInterrupted();




 /**
     *測試線程是否被中斷,並清除中斷狀態,如果被中斷返回true否則返回false,調用兩次得到結果不一樣
     *
     * @see #isInterrupted()
     * @revised 6.0
     */
    @FastNative
    public static native boolean interrupted();



 /**
     * 在A線程中調用了B線程的join()方法時,表示只有當B線程執行完畢時,A線程才能繼續執行。
     *
     *
     * @throws  InterruptedException
     *         如果任何線程中斷了當前線程。當拋出此異常時,當前線程的中斷狀態將被清除。
     */
    public final void join() throws InterruptedException {
        join(0);
    }



/**
     * 在A線程中調用了B線程的join()方法時,表示只有當B線程執行完指定的時間後,A線程才能繼續執行。
     *
     * <p> This implementation uses a loop of {@code this.wait} calls
     * conditioned on {@code this.isAlive}. As a thread terminates the
     * {@code this.notifyAll} method is invoked. It is recommended that
     * applications not use {@code wait}, {@code notify}, or
     * {@code notifyAll} on {@code Thread} instances.
     *
     * @param  millis
     *        等待時間
     *
     * @throws  IllegalArgumentException
     *         參數小於0
     *
     * @throws  InterruptedException
     *          如果任何線程中斷了當前線程。當拋出此異常時,當前線程的中斷狀態將被清除。
     */
    public final void join(long millis) throws InterruptedException {
        synchronized(lock) {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
            //當參數爲0直接運行當前線程
                lock.wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                //阻塞當前線程,直到時間到了
                lock.wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
        }
    }


 /**
     * 休眠當前線程.
     * 
     *這方法已經被啓用,因爲休眠後不釋放鎖,容易死鎖    
     *
     */
     //過時的
    @Deprecated
    public final void suspend() {
        throw new UnsupportedOperationException();
    }


    /**
     * 過時方法,此方法僅用於與suspend()一起使用,喚醒一個線程,
     */
    @Deprecated
    public final void resume() {
        throw new UnsupportedOperationException();
    }



/**
     *
     *這個方法過時了,用來停止線程(導致線程運行一半突然停止)沒辦法完成一個基本單位的操作,同時釋放鎖,這樣導致線程不安全
     */
    @Deprecated
    public final void stop() {
        stop(new ThreadDeath());
    }


/**
     * 
     * 使得當前線程放棄CPU執行權,讓線程從運行狀態到就緒狀態,但是不釋放鎖資源,狀態任然是可運行狀態
     * 如果某一個線程是不太緊急的線程,可以在編寫時調用yield()這樣會讓其它線程得到更多的執行機會
     */
    public static native void yield();

總結一下,如果要暫停線程推薦使用 interrupt()去通知目標線程是否中斷執行,而不是stop、suspend和ruseme強行中斷,詳情請看多線程核心知識(二)

Object類和線程先關的方法

/**
     *使當前線程等待,直到另外一個線程調用此對象的notify()方法或notifyAll()方法喚醒去繼續獲得cpu執行     
     *權,或者等待指定時間重新去繼續獲得cpu執行權,調用此方法會釋放鎖資源
     *
     * @param      millis   時間毫秒值
     * @throws  IllegalArgumentException      如果參數爲負數
     *               
     * @throws  IllegalMonitorStateException 
     *              如果當前線程不是對象監視器的所有者。
     * @throws  InterruptedException 
     *             如果被其他線程打斷報異常,而且清除中斷狀態
     * @see        java.lang.Object#notify()
     * @see        java.lang.Object#notifyAll()
     */
    public final void wait(long millis) throws InterruptedException {
        wait(millis, 0);
    }
    

    /**
     * 引起當前線程等待,釋放鎖,直到另一個線程爲此對象調用notify()方法或notifyAll()方法。線程繼續設               
     * 法獲得執行權
     * 
     * 此方法只能由鎖的獲得者的線程調用
     *
     * @throws  IllegalMonitorStateException 如果當前線程不是對象監視器的所有者。
     * @throws  InterruptedException 
     *               線程被其他線程打斷拋出異常,並清除中斷狀態
     * @see        java.lang.Object#notify()
     * @see        java.lang.Object#notifyAll()
     */
    @FastNative
    public final native void wait() throws InterruptedException;



/**
     * 隨機喚醒等待集中某一個線程
     *
     * @throws  IllegalMonitorStateException 如果當前線程不是此對象監視器的所有者。
     * @see        java.lang.Object#notifyAll()
     * @see        java.lang.Object#wait()
     */
    @FastNative
    public final native void notify();




/**
     * 喚醒等待集中所有線程
     *
     *
     * @throws  IllegalMonitorStateException  如果當前線程不是此對象監視器的所有者。
     *           
     * @see        java.lang.Object#notify()
     * @see        java.lang.Object#wait()
     */
    @FastNative
    public final native void notifyAll();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章