閱讀大約倆分鐘
java
原來ThreadLocal的Lambda構造方式這麼簡單安全
ThreadLocal的Lambda構造方式ide
Java8 中 ThreadLocal 對象提供了一個 Lambda構造方式,實現了很是簡潔的構造方法:withInitial。這個方法採用 Lambda 方式傳入實現了 Supplier 函數接口的參數。寫法以下:函數
/** * 當前餘額 */ private ThreadLocal<Integer> balance = ThreadLocal.withInitial(() -> 1000);
用ThreadLocal做爲容器,當每一個線程訪問這個 balance 變量時,ThreadLocal會爲每一個線程提供一份變量,各個線程互不影響。this
附帶一個銀行存款的例子。線程
package com.javapub.source.code.threadlocal; /** * ThreadLocal的Lambda構造方式:withInitial * * @author */ public class ThreadLocalLambdaDemoByJavaPub { /** * 運行入口 * * @param args 運行參數 */ public static void main(String[] args) { safeDeposit(); //notSafeDeposit(); } /** * 線程安全的存款 */ private static void safeDeposit() { SafeBank bank = new SafeBank(); Thread thread1 = new Thread(() -> bank.deposit(200), "馬雲"); Thread thread2 = new Thread(() -> bank.deposit(200), "馬化騰"); Thread thread3 = new Thread(() -> bank.deposit(500), "p哥"); thread1.start(); thread2.start(); thread3.start(); } /** * 非線程安全的存款 */ private static void notSafeDeposit() { NotSafeBank bank = new NotSafeBank(); Thread thread1 = new Thread(() -> bank.deposit(200), "張成瑤"); Thread thread2 = new Thread(() -> bank.deposit(200), "馬雲"); Thread thread3 = new Thread(() -> bank.deposit(500), "馬化騰"); thread1.start(); thread2.start(); thread3.start(); } } /** * 非線程安全的銀行 */ class NotSafeBank { /** * 當前餘額 */ private int balance = 1000; /** * 存款 * * @param money 存款金額 */ public void deposit(int money) { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " -> 當前帳戶餘額爲:" + this.balance); this.balance += money; System.out.println(threadName + " -> 存入 " + money + " 後,當前帳戶餘額爲:" + this.balance); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 線程安全的銀行 */ class SafeBank { /** * 當前餘額 */ private ThreadLocal<Integer> balance = ThreadLocal.withInitial(() -> 1000); /** * 存款 * * @param money 存款金額 */ public void deposit(int money) { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " -> 當前帳戶餘額爲:" + this.balance.get()); this.balance.set(this.balance.get() + money); System.out.println(threadName + " -> 存入 " + money + " 後,當前帳戶餘額爲:" + this.balance.get()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }