Java8 - ThreadLocal的Lambda构造方式:withInitial

ThreadLocal的Lambda构造方式

Java8中ThreadLocal对象提供了一个Lambda构造方式,实现了非常简洁的构造方法:withInitial。这个方法采用Lambda方式传入实现了 Supplier 函数接口的参数。写法如下:

代码实例

1
2
3
4
/**
* 当前余额
*/
private ThreadLocal<Integer> balance = ThreadLocal.withInitial(() -> 1000);

用ThreadLocal作为容器,当每个线程访问这个 balance 变量时,ThreadLocal会为每个线程提供一份变量,各个线程互不影响。

银行存款实例

附带一个银行存款的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package me.zebe.cat.java.lambda;

/**
* ThreadLocal的Lambda构造方式:withInitial
*
* @author Zebe
*/
public class ThreadLocalLambdaDemo {

/**
* 运行入口
*
* @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), "马化腾");
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();
}
}
}