亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

從源碼的角度再學(xué)「Thread」

abson / 719人閱讀

摘要:前言中的線程是使用類實(shí)現(xiàn)的,在初學(xué)的時(shí)候就學(xué)過了,也在實(shí)踐中用過,不過一直沒從源碼的角度去看過它的實(shí)現(xiàn),今天從源碼的角度出發(fā),再次學(xué)習(xí),愿此后對(duì)的實(shí)踐更加得心應(yīng)手。如果一個(gè)線程已經(jīng)啟動(dòng)并且尚未死亡,則該線程處于活動(dòng)狀態(tài)。

前言

Java中的線程是使用Thread類實(shí)現(xiàn)的,Thread在初學(xué)Java的時(shí)候就學(xué)過了,也在實(shí)踐中用過,不過一直沒從源碼的角度去看過它的實(shí)現(xiàn),今天從源碼的角度出發(fā),再次學(xué)習(xí)Java Thread,愿此后對(duì)Thread的實(shí)踐更加得心應(yīng)手。

從注釋開始

相信閱讀過JDK源碼的同學(xué)都能感受到JDK源碼中有非常詳盡的注釋,閱讀某個(gè)類的源碼應(yīng)當(dāng)先看看注釋對(duì)它的介紹,注釋原文就不貼了,以下是我對(duì)它的總結(jié):

Thread是程序中執(zhí)行的線程,Java虛擬機(jī)允許應(yīng)用程序同時(shí)允許多個(gè)執(zhí)行線程

每個(gè)線程都有優(yōu)先級(jí)的概念,具有較高優(yōu)先級(jí)的線程優(yōu)先于優(yōu)先級(jí)較低的線程執(zhí)行

每個(gè)線程都可以被設(shè)置為守護(hù)線程

當(dāng)在某個(gè)線程中運(yùn)行的代碼創(chuàng)建一個(gè)新的Thread對(duì)象時(shí),新的線程優(yōu)先級(jí)跟創(chuàng)建線程一致

當(dāng)Java虛擬機(jī)啟動(dòng)的時(shí)候都會(huì)啟動(dòng)一個(gè)叫做main的線程,它沒有守護(hù)線程,main線程會(huì)繼續(xù)執(zhí)行,直到以下情況發(fā)送

Runtime 類的退出方法exit被調(diào)用并且安全管理器允許進(jìn)行退出操作

所有非守護(hù)線程均已死亡,或者run方法執(zhí)行結(jié)束正常返回結(jié)果,或者run方法拋出異常

創(chuàng)建線程第一種方式:繼承Thread類,重寫run方法

//定義線程類
class PrimeThread extends Thread {
      long minPrime;
      PrimeThread(long minPrime) {
          this.minPrime = minPrime;
      }
      public void run() {
          // compute primes larger than minPrime
           . . .
      }
  }
//啟動(dòng)線程
PrimeThread p = new PrimeThread(143);
p.start();

創(chuàng)建線程第二種方式:實(shí)現(xiàn)Runnable接口,重寫run方法,因?yàn)?b>Java的單繼承限制,通常使用這種方式創(chuàng)建線程更加靈活

//定義線程
 class PrimeRun implements Runnable {
      long minPrime;
      PrimeRun(long minPrime) {
          this.minPrime = minPrime;
      }
      public void run() {
          // compute primes larger than minPrime
           . . .
      }
  }
//啟動(dòng)線程
PrimeRun p = new PrimeRun(143);
new Thread(p).start();

創(chuàng)建線程時(shí)可以給線程指定名字,如果沒有指定,會(huì)自動(dòng)為它生成名字

除非另有說明,否則將null參數(shù)傳遞給Thread類中的構(gòu)造函數(shù)或方法將導(dǎo)致拋出 NullPointerException

Thread 常用屬性

閱讀一個(gè)Java類,先從它擁有哪些屬性入手:

//線程名稱,創(chuàng)建線程時(shí)可以指定線程的名稱
private volatile String name;

//線程優(yōu)先級(jí),可以設(shè)置線程的優(yōu)先級(jí)
private int priority;

//可以配置線程是否為守護(hù)線程,默認(rèn)為false
private boolean daemon = false;

//最終執(zhí)行線程任務(wù)的`Runnable`
private Runnable target;

//描述線程組的類
private ThreadGroup group;

//此線程的上下文ClassLoader
private ClassLoader contextClassLoader;

//所有初始化線程的數(shù)目,用于自動(dòng)編號(hào)匿名線程,當(dāng)沒有指定線程名稱時(shí),會(huì)自動(dòng)為其編號(hào)
private static int threadInitNumber;

//此線程請(qǐng)求的堆棧大小,如果創(chuàng)建者沒有指定堆棧大小,則為0。, 虛擬機(jī)可以用這個(gè)數(shù)字做任何喜歡的事情。, 一些虛擬機(jī)會(huì)忽略它。
private long stackSize;

//線程id
private long tid;

//用于生成線程ID
private static long threadSeqNumber;

//線程狀態(tài)
private volatile int threadStatus = 0;

//線程可以擁有的最低優(yōu)先級(jí)
public final static int MIN_PRIORITY = 1;

//分配給線程的默認(rèn)優(yōu)先級(jí)。
public final static int NORM_PRIORITY = 5;

//線程可以擁有的最大優(yōu)先級(jí)
public final static int MAX_PRIORITY = 10;

所有的屬性命名都很語義化,其實(shí)已看名稱基本就猜到它是干嘛的了,難度不大~~

Thread 構(gòu)造方法

了解了屬性之后,看看Thread實(shí)例是怎么構(gòu)造的?先預(yù)覽下它大致有多少個(gè)構(gòu)造方法:

查看每個(gè)構(gòu)造方法內(nèi)部源碼,發(fā)現(xiàn)均調(diào)用的是名為init的私有方法,再看init方法有兩個(gè)重載,而其核心方法如下:

   /**
     * Initializes a Thread.
     *
     * @param g                   線程組
     * @param target              最終執(zhí)行任務(wù)的 `run()` 方法的對(duì)象
     * @param name                新線程的名稱
     * @param stackSize           新線程所需的堆棧大小,或者 0 表示要忽略此參數(shù)
     * @param acc                 要繼承的AccessControlContext,如果為null,則為 AccessController.getContext()
     * @param inheritThreadLocals 如果為 true,從構(gòu)造線程繼承可繼承的線程局部的初始值
     */
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        //線程名稱為空,直接拋出空指針異常
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
        //初始化當(dāng)前線程對(duì)象的線程名稱
        this.name = name;
        //獲取當(dāng)前正在執(zhí)行的線程為父線程
        Thread parent = currentThread();
        //獲取系統(tǒng)安全管理器
        SecurityManager security = System.getSecurityManager();
        //如果線程組為空
        if (g == null) {
            //如果安全管理器不為空
            if (security != null) {
                //獲取SecurityManager中的線程組
                g = security.getThreadGroup();
            }
            //如果獲取的線程組還是為空
            if (g == null) {
                //則使用父線程的線程組
                g = parent.getThreadGroup();
            }
        }
        
        //檢查安全權(quán)限
        g.checkAccess();

        //使用安全管理器檢查是否有權(quán)限
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }
        
        //線程組中標(biāo)記未啟動(dòng)的線程數(shù)+1,這里方法是同步的,防止出現(xiàn)線程安全問題
        g.addUnstarted();
        
        //初始化當(dāng)前線程對(duì)象的線程組
        this.group = g;
        //初始化當(dāng)前線程對(duì)象的是否守護(hù)線程屬性,注意到這里初始化時(shí)跟父線程一致
        this.daemon = parent.isDaemon();
        //初始化當(dāng)前線程對(duì)象的線程優(yōu)先級(jí)屬性,注意到這里初始化時(shí)跟父線程一致
        this.priority = parent.getPriority();
        //這里初始化類加載器
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        //初始化當(dāng)前線程對(duì)象的最終執(zhí)行任務(wù)對(duì)象
        this.target = target;
        //這里再對(duì)線程的優(yōu)先級(jí)字段進(jìn)行處理
        setPriority(priority);
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        //初始化當(dāng)前線程對(duì)象的堆棧大小
        this.stackSize = stackSize;

        //初始化當(dāng)前線程對(duì)象的線程ID,該方法是同步的,內(nèi)部實(shí)際上是threadSeqNumber++
        tid = nextThreadID();
    }

另一個(gè)重載init私有方法如下,實(shí)際上內(nèi)部調(diào)用的是上述init方法:

private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }

接下來看看所有構(gòu)造方法:

空構(gòu)造方法

 public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

內(nèi)部調(diào)用的是init第二個(gè)重載方法,參數(shù)基本都是默認(rèn)值,線程名稱寫死為"Thread-" + nextThreadNum()格式,nextThreadNum()為一個(gè)同步方法,內(nèi)部維護(hù)一個(gè)靜態(tài)屬性表示線程的初始化數(shù)量+1:

 private static int threadInitNumber;
    private static synchronized int nextThreadNum() {
        return threadInitNumber++;
    }

自定義執(zhí)行任務(wù)Runnable對(duì)象的構(gòu)造方法

public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

與第一個(gè)構(gòu)造方法區(qū)別在于可以自定義Runnable對(duì)象

自定義執(zhí)行任務(wù)Runnable對(duì)象和AccessControlContext對(duì)象的構(gòu)造方法

 Thread(Runnable target, AccessControlContext acc) {
    init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}

自定義線程組ThreadGroup和執(zhí)行任務(wù)Runnable對(duì)象的構(gòu)造方法

public Thread(ThreadGroup group, Runnable target) {
    init(group, target, "Thread-" + nextThreadNum(), 0);
}

自定義線程名稱name的構(gòu)造方法

 public Thread(String name) {
    init(null, null, name, 0);
}

自定義線程組ThreadGroup和線程名稱name的構(gòu)造方法

 public Thread(ThreadGroup group, String name) {
    init(group, null, name, 0);
}

自定義執(zhí)行任務(wù)Runnable對(duì)象和線程名稱name的構(gòu)造方法

 public Thread(Runnable target, String name) {
    init(null, target, name, 0);
}

自定義線程組ThreadGroup和線程名稱name和執(zhí)行任務(wù)Runnable對(duì)象的構(gòu)造方法

  public Thread(ThreadGroup group, Runnable target, String name) {
    init(group, target, name, 0);
}

全部屬性都是自定義的構(gòu)造方法

  public Thread(ThreadGroup group, Runnable target, String name,
              long stackSize) {
    init(group, target, name, stackSize);
}

Thread提供了非常靈活的重載構(gòu)造方法,方便開發(fā)者自定義各種參數(shù)的Thread對(duì)象。

常用方法

這里記錄一些比較常見的方法吧,對(duì)于Thread中存在的一些本地方法,我們暫且不用管它~

設(shè)置線程名稱

設(shè)置線程名稱,該方法為同步方法,為了防止出現(xiàn)線程安全問題,可以手動(dòng)調(diào)用Thread的實(shí)例方法設(shè)置名稱,也可以在構(gòu)造Thread時(shí)在構(gòu)造方法中傳入線程名稱,我們通常都是在構(gòu)造參數(shù)時(shí)設(shè)置

   public final synchronized void setName(String name) {
         //檢查安全權(quán)限
          checkAccess();
         //如果形參為空,拋出空指針異常
          if (name == null) {
              throw new NullPointerException("name cannot be null");
          }
        //給當(dāng)前線程對(duì)象設(shè)置名稱
          this.name = name;
          if (threadStatus != 0) {
              setNativeName(name);
          }
      }
獲取線程名稱

內(nèi)部直接返回當(dāng)前線程對(duì)象的名稱屬性

  public final String getName() {
        return name;
    }
啟動(dòng)線程
public synchronized void start() {
        //如果不是剛創(chuàng)建的線程,拋出異常
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        //通知線程組,當(dāng)前線程即將啟動(dòng),線程組當(dāng)前啟動(dòng)線程數(shù)+1,未啟動(dòng)線程數(shù)-1
        group.add(this);
        
        //啟動(dòng)標(biāo)識(shí)
        boolean started = false;
        try {
            //直接調(diào)用本地方法啟動(dòng)線程
            start0();
            //設(shè)置啟動(dòng)標(biāo)識(shí)為啟動(dòng)成功
            started = true;
        } finally {
            try {
                //如果啟動(dòng)呢失敗
                if (!started) {
                    //線程組內(nèi)部移除當(dāng)前啟動(dòng)的線程數(shù)量-1,同時(shí)啟動(dòng)失敗的線程數(shù)量+1
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

我們正常的啟動(dòng)線程都是調(diào)用Threadstart()方法,然后Java虛擬機(jī)內(nèi)部會(huì)去調(diào)用Thredrun方法,可以看到Thread類也是實(shí)現(xiàn)Runnable接口,重寫了run方法的:

 @Override
    public void run() {
        //當(dāng)前執(zhí)行任務(wù)的Runnable對(duì)象不為空,則調(diào)用其run方法
        if (target != null) {
            target.run();
        }
    }

Thread的兩種使用方式:

繼承Thread類,重寫run方法,那么此時(shí)是直接執(zhí)行run方法的邏輯,不會(huì)使用 target.run();

實(shí)現(xiàn)Runnable接口,重寫run方法,因?yàn)?b>Java的單繼承限制,通常使用這種方式創(chuàng)建線程更加靈活,這里真正的執(zhí)行邏輯就會(huì)交給自定義Runnable去實(shí)現(xiàn)

設(shè)置守護(hù)線程

本質(zhì)操作是設(shè)置daemon屬性

public final void setDaemon(boolean on) {
        //檢查是否有安全權(quán)限
        checkAccess();
        //本地方法,測(cè)試此線程是否存活。, 如果一個(gè)線程已經(jīng)啟動(dòng)并且尚未死亡,則該線程處于活動(dòng)狀態(tài)
        if (isAlive()) {
            //如果線程先啟動(dòng)后再設(shè)置守護(hù)線程,將拋出異常
            throw new IllegalThreadStateException();
        }
        //設(shè)置當(dāng)前守護(hù)線程屬性
        daemon = on;
    }
判斷線程是否為守護(hù)線程
 public final boolean isDaemon() {
        //直接返回當(dāng)前對(duì)象的守護(hù)線程屬性
        return daemon;
    }
線程狀態(tài)

先來個(gè)線程狀態(tài)圖:

獲取線程狀態(tài):

 public State getState() {
        //由虛擬機(jī)實(shí)現(xiàn),獲取當(dāng)前線程的狀態(tài)
        return sun.misc.VM.toThreadState(threadStatus);
    }

線程狀態(tài)主要由內(nèi)部枚舉類State組成:

  public enum State {
      
        NEW,

      
        RUNNABLE,

      
        BLOCKED,

       
        WAITING,

       
        TIMED_WAITING,

       
        TERMINATED;
    }

NEW:剛剛創(chuàng)建,尚未啟動(dòng)的線程處于此狀態(tài)

RUNNABLE:在Java虛擬機(jī)中執(zhí)行的線程處于此狀態(tài)

BLOCKED:被阻塞等待監(jiān)視器鎖的線程處于此狀態(tài),比如線程在執(zhí)行過程中遇到synchronized同步塊,就會(huì)進(jìn)入此狀態(tài),此時(shí)線程暫停執(zhí)行,直到獲得請(qǐng)求的鎖

WAITING:無限期等待另一個(gè)線程執(zhí)行特定操作的線程處于此狀態(tài)

通過 wait() 方法等待的線程在等待 notify() 方法

通過 join() 方法等待的線程則會(huì)等待目標(biāo)線程的終止

TIMED_WAITING:正在等待另一個(gè)線程執(zhí)行動(dòng)作,直到指定等待時(shí)間的線程處于此狀態(tài)

通過 wait() 方法,攜帶超時(shí)時(shí)間,等待的線程在等待 notify() 方法

通過 join() 方法,攜帶超時(shí)時(shí)間,等待的線程則會(huì)等待目標(biāo)線程的終止

TERMINATED:已退出的線程處于此狀態(tài),此時(shí)線程無法再回到 RUNNABLE 狀態(tài)

線程休眠

這是一個(gè)靜態(tài)的本地方法,使當(dāng)前執(zhí)行的線程休眠暫停執(zhí)行 millis 毫秒,當(dāng)休眠被中斷時(shí)會(huì)拋出InterruptedException中斷異常

    /**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds, subject to
     * the precision and accuracy of system timers and schedulers. The thread
     * does not lose ownership of any monitors.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          interrupted status of the current thread is
     *          cleared when this exception is thrown.
     */
    public static native void sleep(long millis) throws InterruptedException;
檢查線程是否存活

本地方法,測(cè)試此線程是否存活。 如果一個(gè)線程已經(jīng)啟動(dòng)并且尚未死亡,則該線程處于活動(dòng)狀態(tài)。

    /**
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     *
     * @return  true if this thread is alive;
     *          false otherwise.
     */
    public final native boolean isAlive();
線程優(yōu)先級(jí)

設(shè)置線程優(yōu)先級(jí)

    /**
     * Changes the priority of this thread.
     * 

* First the checkAccess method of this thread is called * with no arguments. This may result in throwing a * SecurityException. *

* Otherwise, the priority of this thread is set to the smaller of * the specified newPriority and the maximum permitted * priority of the thread"s thread group. * * @param newPriority priority to set this thread to * @exception IllegalArgumentException If the priority is not in the * range MIN_PRIORITY to * MAX_PRIORITY. * @exception SecurityException if the current thread cannot modify * this thread. * @see #getPriority * @see #checkAccess() * @see #getThreadGroup() * @see #MAX_PRIORITY * @see #MIN_PRIORITY * @see ThreadGroup#getMaxPriority() */ public final void setPriority(int newPriority) { //線程組 ThreadGroup g; //檢查安全權(quán)限 checkAccess(); //檢查優(yōu)先級(jí)形參范圍 if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); } if((g = getThreadGroup()) != null) { //如果優(yōu)先級(jí)形參大于線程組最大線程最大優(yōu)先級(jí) if (newPriority > g.getMaxPriority()) { //則使用線程組的優(yōu)先級(jí)數(shù)據(jù) newPriority = g.getMaxPriority(); } //調(diào)用本地設(shè)置線程優(yōu)先級(jí)方法 setPriority0(priority = newPriority); } }

線程中斷

有一個(gè)stop()實(shí)例方法可以強(qiáng)制終止線程,不過這個(gè)方法因?yàn)樘^于暴力,已經(jīng)被標(biāo)記為過時(shí)方法,不建議程序員再使用,因?yàn)?strong>強(qiáng)制終止線程會(huì)導(dǎo)致數(shù)據(jù)不一致的問題。

這里關(guān)于線程中斷的方法涉及三個(gè):

//實(shí)例方法,通知線程中斷,設(shè)置標(biāo)志位
 public void interrupt(){}
 //靜態(tài)方法,檢查當(dāng)前線程的中斷狀態(tài),同時(shí)會(huì)清除當(dāng)前線程的中斷標(biāo)志位狀態(tài)
 public static boolean interrupted(){}
 //實(shí)例方法,檢查當(dāng)前線程是否被中斷,其實(shí)是檢查中斷標(biāo)志位
 public boolean isInterrupted(){}

interrupt() 方法解析

/**
     * Interrupts this thread.
     *
     * 

Unless the current thread is interrupting itself, which is * always permitted, the {@link #checkAccess() checkAccess} method * of this thread is invoked, which may cause a {@link * SecurityException} to be thrown. * *

If this thread is blocked in an invocation of the {@link * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link * Object#wait(long, int) wait(long, int)} methods of the {@link Object} * class, or of the {@link #join()}, {@link #join(long)}, {@link * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)}, * methods of this class, then its interrupt status will be cleared and it * will receive an {@link InterruptedException}. * *

If this thread is blocked in an I/O operation upon an {@link * java.nio.channels.InterruptibleChannel InterruptibleChannel} * then the channel will be closed, the thread"s interrupt * status will be set, and the thread will receive a {@link * java.nio.channels.ClosedByInterruptException}. * *

If this thread is blocked in a {@link java.nio.channels.Selector} * then the thread"s interrupt status will be set and it will return * immediately from the selection operation, possibly with a non-zero * value, just as if the selector"s {@link * java.nio.channels.Selector#wakeup wakeup} method were invoked. * *

If none of the previous conditions hold then this thread"s interrupt * status will be set.

* *

Interrupting a thread that is not alive need not have any effect. * * @throws SecurityException * if the current thread cannot modify this thread * * @revised 6.0 * @spec JSR-51 */ public void interrupt() { //檢查是否是自身調(diào)用 if (this != Thread.currentThread()) //檢查安全權(quán)限,這可能導(dǎo)致拋出{@link * SecurityException}。 checkAccess(); //同步代碼塊 synchronized (blockerLock) { Interruptible b = blocker; //檢查是否是阻塞線程調(diào)用 if (b != null) { //設(shè)置線程中斷標(biāo)志位 interrupt0(); //此時(shí)拋出異常,將中斷標(biāo)志位設(shè)置為false,此時(shí)我們正常會(huì)捕獲該異常,重新設(shè)置中斷標(biāo)志位 b.interrupt(this); return; } } //如無意外,則正常設(shè)置中斷標(biāo)志位 interrupt0(); }

線程中斷方法不會(huì)使線程立即退出,而是給線程發(fā)送一個(gè)通知,告知目標(biāo)線程,有人希望你退出啦~

只能由自身調(diào)用,否則可能會(huì)拋出 SecurityException

調(diào)用中斷方法是由目標(biāo)線程自己決定是否中斷,而如果同時(shí)調(diào)用了wait,join,sleep等方法,會(huì)使當(dāng)前線程進(jìn)入阻塞狀態(tài),此時(shí)有可能發(fā)生InterruptedException異常

被阻塞的線程再調(diào)用中斷方法是不合理的

中斷不活動(dòng)的線程不會(huì)產(chǎn)生任何影響

檢查線程是否被中斷:

    /**
     * Tests whether this thread has been interrupted.  The interrupted
     * status of the thread is unaffected by this method.
     
     測(cè)試此線程是否已被中斷。, 線程的中斷*狀態(tài)不受此方法的影響。
     *
     * 

A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return true if this thread has been interrupted; * false otherwise. * @see #interrupted() * @revised 6.0 */ public boolean isInterrupted() { return isInterrupted(false); }

靜態(tài)方法,會(huì)清空當(dāng)前線程的中斷標(biāo)志位:

   /**
     *測(cè)試當(dāng)前線程是否已被中斷。, 此方法清除線程的* 中斷狀態(tài)。, 換句話說,如果要連續(xù)兩次調(diào)用此方法,則* second調(diào)用將返回false(除非當(dāng)前線程再次被中斷,在第一次調(diào)用已清除其中斷的*狀態(tài)   之后且在第二次調(diào)用已檢查之前), 它)
     *
     * 

A thread interruption ignored because a thread was not alive * at the time of the interrupt will be reflected by this method * returning false. * * @return true if the current thread has been interrupted; * false otherwise. * @see #isInterrupted() * @revised 6.0 */ public static boolean interrupted() { return currentThread().isInterrupted(true); }

總結(jié)

記錄自己閱讀Thread類源碼的一些思考,不過對(duì)于其中用到的很多本地方法只能望而卻步,還有一些代碼沒有看明白,暫且先這樣吧,如果有不足之處,請(qǐng)留言告知我,謝謝!后續(xù)會(huì)在實(shí)踐中對(duì)Thread做出更多總結(jié)記錄。

最后

由于篇幅較長,暫且先記錄這些吧,后續(xù)會(huì)不定期更新原創(chuàng)文章,歡迎關(guān)注公眾號(hào) 「張少林同學(xué)」!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/73112.html

相關(guān)文章

  • JAVA 中 CAS

    摘要:我們繼續(xù)看代碼的意思是這個(gè)是一段內(nèi)嵌匯編代碼。也就是在語言中使用匯編代碼。就是匯編版的比較并交換。就是保證在多線程情況下,不阻塞線程的填充和消費(fèi)。微觀上看匯編的是實(shí)現(xiàn)操作系統(tǒng)級(jí)別的原子操作的基石。 原文地址:https://www.xilidou.com/2018/02/01/java-cas/ CAS 是現(xiàn)代操作系統(tǒng),解決并發(fā)問題的一個(gè)重要手段,最近在看 eureka 的源碼的時(shí)候。...

    CocoaChina 評(píng)論0 收藏0
  • vue創(chuàng)建到完整餓了么(2)路由

    摘要:首先在下創(chuàng)建文件夾,在下創(chuàng)建文件,所有的路由控制都寫在這個(gè)文件里。表示路徑,表示顯示的頁面要顯示哪個(gè)文件,表示的嵌套的路由。 說明 上一篇地址--創(chuàng)建 蒼渡大神Github項(xiàng)目源碼地址--源碼地址 下一篇地址--引入U(xiǎn)I框架 home.vue 創(chuàng)建 根據(jù)源碼,先在src文件夾下新建文件夾page,在page中新建home文件夾,在home文件夾中新建home.vue,hom...

    mmy123456 評(píng)論0 收藏0
  • Thread源碼解讀(3)——線程中斷interrupt

    摘要:現(xiàn)在終止一個(gè)線程,基本上只能靠曲線救國式的中斷來實(shí)現(xiàn)。中斷機(jī)制的核心在于中斷狀態(tài)和異常中斷狀態(tài)設(shè)置一個(gè)中斷狀態(tài)清除一個(gè)中斷狀態(tài)方法同時(shí)會(huì)返回線程原來的中斷的狀態(tài)。中斷異常中斷異常一般是線程被中斷后,在一些類型的方法如中拋出。 前言 系列文章目錄 線程中斷是一個(gè)很重要的概念,通常,取消一個(gè)任務(wù)的執(zhí)行,最好的,同時(shí)也是最合理的方法,就是通過中斷。 本篇我們主要還是通過源碼分析來看看中斷的概...

    fevin 評(píng)論0 收藏0
  • Java面試題必備知識(shí)之ThreadLocal

    摘要:方法,刪除當(dāng)前線程綁定的這個(gè)副本數(shù)字,這個(gè)值是的值,普通的是使用鏈表來處理沖突的,但是是使用線性探測(cè)法來處理沖突的,就是每次增加的步長,根據(jù)參考資料所說,選擇這個(gè)數(shù)字是為了讓沖突概率最小。 showImg(https://segmentfault.com/img/remote/1460000019828633); 老套路,先列舉下關(guān)于ThreadLocal常見的疑問,希望可以通過這篇學(xué)...

    Maxiye 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

abson

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<