JAVA併發之多線程基礎(1)

在JAVA中,談到併發問題確定是談到多線程相關。能夠說這兩個之間有着必定的關係。在這裏就爲你們簡單的說下多線程的基礎,以後的文章中會繼續講解多線程相關。java

什麼是線程

線程是進程內的執行單元。一個進程中含有若干個線程,線程能夠看作粒度更小的任務執行單元。進程之間切換,消耗的資源是很大的。經過線程去處理會很好的節省相關資源。多線程

線程狀態轉化

這上面是針對於線程的狀態轉化一個簡單描述。這上面能夠看到blocked的之間的狀態只有一條線來回。這塊的話關乎到sychronized的底層實現原理,你們能夠自行了解下。這裏面我就省略了一個Running的一個狀態。Running的狀態在可運行狀態(Runnable)以後。併發

線程實現幾種方式

  • 繼承Thread類
  • 實現Runnable接口
  • 實現Callable接口

上面是是實現線程的三種方式。在調用線程時候,調用的是其start()方法,而不是調用的run()方法。其中第三種實現方式結合Future能夠獲取到線程的返回值(同時,在線程池裏面運行多線程的話,使用exec.execute()是拿不到線程執行的返回值,使用exec.submit()能夠經過上面的Future取得線程執行的返回值)。this

線程方法

1.stop(),這個方法使得當前所運行的線程中止,釋放全部的monitor。可是使用這個方法會致使多線程的數據不一致性(假設兩個線程執行中去中止,再次操做的時候,線程2有可能搶到本來線程1執行的步驟上)。spa

@Deprecated   //提示過時方法
    public final void stop() {
        //獲取SecurityManager進行校驗
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            checkAccess();
            if (this != Thread.currentThread()) {
                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        if (threadStatus != 0) {
            // 若是線程被掛起,則喚醒線程;不然不執行任何操做
            resume(); 
        }

        // 調用系統方法去中止線程
        stop0(new ThreadDeath());
    }
複製代碼

2.interrupt(),這個方法會設置線程中斷狀態。是一個比較合理使用的一個方法。線程

public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();

        synchronized (blockerLock) {//加鎖控制
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();  // 設置中斷位
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }
複製代碼

3.interrupted()判斷當前線程是否被中斷,而且清除當前線程中斷狀態。code

public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }
複製代碼

4.sleep()方法是讓線程等待的。在大多數線程等待的方法中都會拋出InterruptedException異常。同時該方法不會釋放鎖以及所佔用的資源。同時它會清除中斷標誌,因此在catch中再對該線程設置下中斷標誌。cdn

public static native void sleep(long millis) throws InterruptedException;
複製代碼

5.suspend()方法是讓當前線程掛起,不會釋放鎖。blog

@Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }
複製代碼

6.resume()方法是讓線程繼續執行。使用這個的方法就有一個注意點,若是調用這個方法在suspend以前,那麼線程就會永久的掛起,這個時候就會永久的佔用了資源,可能會致使死鎖的發生。繼承

@Deprecated
    public final void resume() {
        checkAccess();
        resume0();
    }
複製代碼

7.join()的主要做用就是同步,它可使得線程之間的並行執行變爲串行執行。

public final synchronized void join(long millis) throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

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

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }
複製代碼

這裏面實際上調用的仍是Object中的wait()方法。

這塊也是對於當前使用最多的線程操做方法作了一個小的總結,在下一講中我會談及到JUC下面的各個鎖操做。

相關文章
相關標籤/搜索