java線程中ThreadLocal類的使用及介紹

yubao16898 8年前發布 | 12K 次閱讀 Java開發

來自: http://blog.csdn.net//chenleixing/article/details/42373507


ThreadLocal總結
1、ThreadLocal使用場合主要解決多線程中數據數據因并發產生不一致問題。ThreadLocal為每個線程的中并發訪問的數據提供一個副本,通過訪問副本來運行業務,這樣的結果是耗費了內存,單大大減少了線程同步所帶來性能消耗,也減少了線程并發控制的復雜度。
2、ThreadLocal不能使用原子類型,只能使用Object類型。ThreadLocal的使用比synchronized要簡單得多。
3、ThreadLocal和Synchonized都用于解決多線程并發訪問。但是ThreadLocal與synchronized有本質的區別。synchronized是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而ThreadLocal為每一個線程都提供了變量的副本,使得每個線程在某時間訪問到的并不是同一個對象,這樣就隔離了多個線程對數據的數據共享。而Synchronized卻正好相反,它用于在多個線程間通信時能夠獲得數據共享。
4、Synchronized用于線程間的數據共享,而ThreadLocal則用于線程間的數據隔離。
5、ThreadLocal并不能替代synchronized,它們處理不同的問題域。Synchronized用于實現同步機制,比ThreadLocal更加復雜。
復制代碼
import java.util.Random;

/**
* ThreadLocal實例
* 源自http://lavasoft.blog.51cto.com/62575/51926/
* @author yinchuan.chen
*
*/
public class ThreadLocalDemo implements Runnable {
//創建線程局部變量studentLocal,在后面你會發現用來保存Student對象
private final static ThreadLocal studentLocal = new ThreadLocal();

public static void main(String[] agrs) {
ThreadLocalDemo td = new ThreadLocalDemo();
Thread t1 = new Thread(td, "a");
Thread t2 = new Thread(td, "b");
t1.start();
t2.start();
}

public void run() {
accessStudent();
}

/**
* 示例業務方法,用來測試
*/
public void accessStudent() {
//獲取當前線程的名字
String currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " is running!");
//產生一個隨機數并打印
Random random = new Random();
int age = random.nextInt(100);
System.out.println("thread " + currentThreadName + " set age to:" + age);
//獲取一個Student對象,并將隨機數年齡插入到對象屬性中
Student student = getStudent();
student.setAge(age);
System.out.println("thread " + currentThreadName + " first read age is:" + student.getAge());
try {
Thread.sleep(500);
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("thread " + currentThreadName + " second read age is:" + student.getAge());
}

protected Student getStudent() {
//獲取本地線程變量并強制轉換為Student類型
Student student = (Student) studentLocal.get();
//線程首次執行此方法的時候,studentLocal.get()肯定為null
if (student == null) {
//創建一個Student對象,并保存到本地線程變量studentLocal中
student = new Student();
studentLocal.set(student);
}
return student;
}
}

class Student {
private int age = 0; //年齡

public int getAge() {
return this.age;
}

public void setAge(int age) {
this.age = age;
}
}
復制代碼

本文源自 http://lavasoft.blog.51cto.com/62575/51926/

 本文由用戶 yubao16898 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!