本例子主要目的鳍怨,給每個(gè)線程賦予單獨(dú)的變量副本呻右,使各線程之間不互相影響
/**
* @Package: com.example.thread
* @Description: 序列號生成器
* @author: liuxin
* @date: 17/3/31 下午1:50
*/
public interface Sequence {
int getNumber();
}
/**
* @Package: com.example.thread
* @Description: 每個(gè)線程調(diào)用都會刷新值去覆蓋,所以鞋喇,所有線程共同消費(fèi)number
* @author: liuxin
* @date: 17/3/31 下午1:51
*/
public class SequenceA implements Sequence {
private static volatile int number=0;
@Override
public int getNumber() {
number=number+1;
return number;
}
}
/**
* @Package: com.example.thread
* @Description: 局部線程變量池声滥,每個(gè)線程使用自己的,所以各個(gè)線程之間不共享
* @author: liuxin
* @date: 17/3/31 下午1:58
*/
public class SequenceB implements Sequence {
/**
* 當(dāng)使用ThreadLocal維護(hù)變量時(shí)侦香,ThreadLocal為每個(gè)使用該變量的線程提供獨(dú)立的變量副本落塑,
* 所以每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會影響其它線程所對應(yīng)的副本罐韩。
* 從線程的角度看憾赁,目標(biāo)變量就象是線程的本地變量,這也是類名中“Local”所要表達(dá)的意思散吵。
*/
private static ThreadLocal<Integer> numberContainer = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
@Override
public int getNumber() {
numberContainer.set(numberContainer.get() + 1);
return numberContainer.get();
}
}
/**
* @Package: com.example.thread
* @Description: 多線程
* @author: liuxin
* @date: 17/3/23 下午4:35
*/
public class MyThread extends Thread {
Sequence sequence;
MyThread(Sequence sequence) {
this.sequence = sequence;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "<---->" + sequence.getNumber());
}
}
public static void main(String[] args) {
Sequence sequence = new SequenceA();
MyThread t0 = new MyThread(sequence);
MyThread t1 = new MyThread(sequence);
MyThread t2 = new MyThread(sequence);
t0.start();t0.setPriority(10);
t1.start();t1.setPriority(9);
t2.start();t2.setPriority(8);
Sequence sequence1 = new SequenceB();
MyThread t3 = new MyThread(sequence1);
MyThread t4 = new MyThread(sequence1);
MyThread t5 = new MyThread(sequence1);
t3.start();t3.setPriority(7);
t4.start();t4.setPriority(6);
t5.start();t5.setPriority(5);
}
}
Thread-0<---->1
Thread-0<---->2
Thread-0<---->3
Thread-1<---->4
Thread-1<---->5
Thread-1<---->6
Thread-2<---->7
Thread-2<---->8
Thread-2<---->9
Thread-3<---->1
Thread-4<---->1
Thread-3<---->2
Thread-5<---->1
Thread-3<---->3
Thread-4<---->2
Thread-5<---->2
Thread-5<---->3
Thread-4<---->3
自定義一個(gè)ThreadLocal龙考,設(shè)計(jì)思路就是為每個(gè)線程保存一個(gè)變量副本
使用Map實(shí)現(xiàn)
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* @Package: com.example.thread
* @Description: 手動實(shí)現(xiàn)一個(gè)TheadLocal
* @author: liuxin
* @date: 17/3/31 下午2:22
*/
public class MyTheadLocal<T> {
private Map<Thread, T> container = Collections.synchronizedMap(new HashMap<Thread, T>());
public void set(T value){
container.put(Thread.currentThread(),value);
}
public T get(){
return container.get(Thread.currentThread());
}
public void remove(){
container.remove(Thread.currentThread());
}
protected T initialValue(){
return null;
}
}