不加锁,用空间换时间:(在一定情况下减少锁竞争)
线程局部变量,是一种多线程间并发访问变量的解决方案。与其synchronized等
加锁的方式不同,ThreadLocal完全不提供锁,而使用以空间换时间的手段,为每
个线程提供变量的独立副本,以保障线程安全。
从性能上说,ThreadLocal不具有绝对的优势,在并发不是很高的时候,加锁的性
能会更好,但作为一套与锁完全无关的线程安全解决方案,在高并发量或者竞争激
烈的场景,使用ThreadLocal可以在一定程度上减少锁竞争
ThreadLoacl用法1
如果是对该字符ThreadLoacl<String>串操作,能保证该字符串在多线程内不会错乱。如果字符串是StringBuffer,用多线程对其进行修改,则该字符串会受其他线程影响错乱
package com.bfxy.thread.core.safely;
public class UseThreadLocal {
public static ThreadLocal<String> threadLocal = new ThreadLocal<>();
public void setThreadLocal(String value) {
threadLocal.set(value);
}
public String getThreadLocal(){
return threadLocal.get();
}
public static void main(String[] args) {
UseThreadLocal utl = new UseThreadLocal();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
utl.setThreadLocal("张三");
System.err.println("当前t1: " + utl.getThreadLocal());
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
utl.setThreadLocal("李四");
System.err.println("当前t2: " + utl.getThreadLocal());
}
}, "t2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t1.start();
t2.start();
System.err.println("当前值: " + utl.getThreadLocal());
}
}
ThreadLoacl用法2
package com.bfxy.thread.core.safely;
import java.util.ArrayList;
import java.util.List;
public class MessageHolder {
private List<String> messages = new ArrayList<>();
public static final ThreadLocal<MessageHolder> holder = new ThreadLocal(){
@Override
protected Object initialValue(){
return new MessageHolder();
}
};
public static void add(String message) {
holder.get().messages.add(message);
}
public static List<String> clear(){
List<String> result = holder.get().messages;
holder.remove();
System.err.println("size: " + holder.get().messages.size());
return result;
}
public static void main(String[] args) {
MessageHolder.add("1111");
MessageHolder.add("2222");
List<String> result = MessageHolder.clear();
System.err.println(result.toString());
}
/**
public synchronized allmethod () {
return 1,2 = m1();
return 3,4 = m2(1, 2);
return 5,6 = m3(3, 4);
all return 123456
}
*/
}