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

NO IMAGE

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

在JAVA中,談到併發問題肯定是談到多線程相關。可以說這兩個之間有著一定的關係。在這裡就為大家簡單的說下多線程的基礎,之後的文章中會繼續講解多線程相關。

什麼是線程

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

線程狀態轉化

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

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

線程實現幾種方式

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

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

線程方法

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

    @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()判斷當前線程是否被中斷,並且清除當前線程中斷狀態。

 public static boolean interrupted() {
return currentThread().isInterrupted(true);
}

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

    public static native void sleep(long millis) throws InterruptedException;

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

    @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下面的各個鎖操作。

相關文章

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

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

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

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