JavaRush /Java Blog /Random-TW /喝咖啡休息#160。深入研究 Java ThreadLocal。Java 中的掃描器類

喝咖啡休息#160。深入研究 Java ThreadLocal。Java 中的掃描器類

在 Random-TW 群組發布

深入研究 Java ThreadLocal

來源: Devgenios 今天您將了解 ThreadLocal,它是開發 Java 應用程式時使用的常用類別之一。 喝咖啡休息#160。 深入研究 Java ThreadLocal。 Java 中的掃描器類別 - 1

什麼是ThreadLocal?

ThreadLocal類別儲存線程的局部變數。這些變數在不同執行緒之間是隔離的,只能被自己的執行緒存取。ThreadLocal的用例:
  1. 隔離線程之間的資料。
  2. 資料庫連線的會話管理。
  3. 儲存線程事務資訊。

如何使用ThreadLocal?

讓我們來看一個簡單的例子。
public static void main(String[] args) {
    //Создаем ThreadLocal
    ThreadLocal<String> local = new ThreadLocal<>();
    //Создаем новый класс Random
    Random random = new Random();
    //Создаем 5 потоков
    IntStream.range(0, 5).forEach(a-> new Thread(()-> {
        //Присваиваем meaning каждому потоку
        local.set(a+"  "+random.nextInt(100));
        System.out.println("Thread number and its local value  "+ local.get());
    }).start());
}
在上面的程式碼中,我們創建了一個ThreadLocal類,創建了5個線程,在每個線程中為ThreadLocal賦值並列印。輸出時我們得到: 喝咖啡休息#160。 深入研究 Java ThreadLocal。 Java 中的掃描器類別 - 2

引擎蓋下是什麼?

如果你仔細觀察,從這個程式碼範例你可以看到ThreadLocal中有兩個重要的方法。
  • 公共 T get() {}

  • public void set(T值){}

我們來看看ThreadLocal原始碼中的setter方法:
public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
}
setter 方法首先取得目前線程,並呼叫getMap()方法取得ThreadLocalMap類別。如果map存在,則以目前流t為key,輸入參數為value,將{key:value}對設為map。如果沒有,則建立一個地圖。現在你可能有一個問題 - 什麼是ThreadLocalMap
static class ThreadLocalMap {
   /**
    * The entries in this hash map extend WeakReference, using
    * its main ref field as the key (which is always a
    * ThreadLocal object).  Note that null keys (i.e. entry.get()
    * == null) mean that the key is no longer referenced, so the
    * entry can be expunged from table.  Such entries are referred to
    * as "stale entries" in the code that follows.
    */
    static class Entry extends WeakReference<ThreadLocal<?>> {
       /** The value associated with this ThreadLocal. */
       Object value;
       Entry(ThreadLocal<?> k, Object v) {
           super(k);
           value = v;
       }
    }
}
ThreadLocalMap是ThreadLocal中的一個內部靜態類,它定義了一個Entry類別來儲存資料。Entry使用ThreadLocal實例作為鍵並設定我們傳遞的值。如果這聽起來太令人困惑,請記住,實際儲存值的是ThreadLocalMap中的Entry類別。為了從ThreadLocal取得數據,我們使用getter方法:
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
}
getter方法中,我們將使用currentThread作為鍵來取得ThreadLocalMap。然後map會根據ThreadLocal實例getEntry()並傳回Entry實例,然後傳回儲存的值。這裡有一個圖表可以幫助您弄清楚: 喝咖啡休息#160。 深入研究 Java ThreadLocal。 Java 中的掃描器類別 - 3喝咖啡休息#160。 深入研究 Java ThreadLocal。 Java 中的掃描器類別 - 4
  1. 每個執行緒都維護對ThreadLocalMap 的引用。

  2. ThreadLocalMap是ThreadLocal的內部靜態類,使用Entry類別進行儲存。

  3. ThreadLocalMap鍵是ThreadLocal 的實例,可以有多個ThreadLocal

  4. ThreadLocal本身不會儲存值,但它是執行緒的關鍵,有助於從ThreadLocalMap取得值。

請注意,最好刪除ThreadLocal,以避免由於Entry類別中的「弱」參考而導致 OOM(記憶體不足錯誤)。

Java 中的掃描器類

來源:Medium 這篇文章將幫助您熟悉 Java 中的 Scanner 類別。 Java中的喝咖啡休息#160。 深入研究 Java ThreadLocal。 Java 中的掃描器類別 - 5Scanner類別是我們想要從使用者那裡取得值時使用的類別。理解它的最簡單方法是透過範例,所以讓我們更清楚地了解它。建立Scanner類別是我們從使用者那裡獲取值所採取的三個步驟之一。第一步是從掃描器類別建立一個物件。
Scanner scan=new Scanner(System.in);
現在我們有一個掃描器物件。該物件將具有Scanner類別的 Scanner 屬性。第一步之後,使用者已經可以輸入想要的值,但是如果我們不引導使用者並在控制台或應用程式中顯示該值,那麼在可用性方面就不會很好。因此,最好告知並指導使用者:
System.out.println("Please enter your name");
String name=scan.next();
System.out.println("Your Name:"+name);
在第一行中,我們詢問用戶我們想從他那裡得到什麼。這實際上與掃描器無關,但向用戶提供提示總是好的。在第二行中,我們將分配使用者輸入資料的值並保存它,以便稍後使用。在最後一行中,我們看到我們可以自行決定使用從使用者收到的值。讓我們在程式碼中添加更多細節:
System.out.println("Please enter your last name");

String lastName=scan.next();

System.out.println("Your Name " + name + " " + "Your Last Name" + lastName);
基本上,我們重複前兩行,詢問用戶該值並保存它。現在,在最後一行中,我們使用了從使用者獲得的兩個值,現在將它們一起使用。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION