多執行緒(七):ThreadLocal
阿新 • • 發佈:2018-11-08
多個執行緒共享同一個物件,所有執行緒都操作同一個物件。
public class ThreadLocalTest {
public static void main(String[] args) {
// 三個執行緒每個執行緒列印3次,所以從0列印到9
IdWorker idWorker = new IdWorker();
new Thread(new MyRunnable(idWorker, "A")).start();
new Thread(new MyRunnable(idWorker, "B")).start();
new Thread(new MyRunnable(idWorker, "C")).start();
}
}
class IdWorker {
private Long id = 0L;
public String generateId(String prefix) {
return prefix + (++id);
}
}
class MyRunnable implements Runnable {
private IdWorker idWorker;
private String prefix;
public MyRunnable(IdWorker idWorker, String prefix) {
this .idWorker = idWorker;
this.prefix = prefix;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(new Date() + "\t" + Thread.currentThread().getName() + "\t" + idWorker.generateId(prefix));
}
}
}
三個執行緒分別操作各自的物件,每個物件分別列印自己的
public class ThreadLocalTest {
public static void main(String[] args) {
// 每個執行緒分別使用各自的IdWorker,所以每個執行緒分別列印自己的0、1、2
// 要想達到每個執行緒分別使用自己的IdWorker,如果N個執行緒就必須建立N個物件
IdWorker idWorkerA = new IdWorker();
IdWorker idWorkerB = new IdWorker();
IdWorker idWorkerC = new IdWorker();
new Thread(new MyRunnable(idWorkerA, "A")).start();
new Thread(new MyRunnable(idWorkerB, "B")).start();
new Thread(new MyRunnable(idWorkerC, "C")).start();
}
}
ThreadLocal(本地執行緒)將一個變數提供給所有執行緒,所有執行緒各自複製一份到自己的執行緒,每個執行緒持有的物件互不影響。
public class ThreadLocal<T> {
ThreadLocal.ThreadLocalMap threadLocals = null;
public ThreadLocal();
protected T initialValue();
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null) {
m.remove(this);
}
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
}
public class ThreadLocalTest {
public static void main(String[] args) {
// 只建立一個物件,但是所有執行緒分別複製該物件,每個執行緒分別持有各自的物件
// 與上一個示例相比,效果相同,但是上個示例建立了N個物件,此示例只建立了一個物件
IdWorker idWorker = new IdWorker();
new Thread(new MyRunnable(idWorker, "A")).start();
new Thread(new MyRunnable(idWorker, "B")).start();
new Thread(new MyRunnable(idWorker, "C")).start();
}
}
class IdWorker {
public static ThreadLocal<Long> threadLocal = new ThreadLocal<Long>() {
@Override
protected Long initialValue() {
return 0L;
}
};
public String generateId(String prefix) {
long currentId = threadLocal.get() + 1;
threadLocal.set(currentId);
return prefix + currentId;
}
}
class MyRunnable implements Runnable {
private IdWorker idWorker;
private String prefix;
public MyRunnable(IdWorker idWorker, String prefix) {
this.idWorker = idWorker;
this.prefix = prefix;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(new Date() + "\t" + Thread.currentThread().getName() + "\t" + idWorker.generateId(prefix));
}
}
}