Java多線程同步問題的探究(五)

來源:互聯網
上載者:User

五、你有我有全都有—— ThreadLocal如何解決並發安全性?

前面我們介紹了Java當中多個線程搶佔一個共用資源的問題。但不論是同步還是重入鎖,都不能實實在在的解決資源緊缺的情況,這些 方案只是靠制定規則來約束線程的行為,讓它們不再拚命的爭搶,而不是真正從實質上解決他們對資源的需求。

在JDK 1.2當中,引入了java.lang.ThreadLocal。它為我們提供了一種全新的思路來解決線程並發的問題。但是他的名字難免讓我們望 文生義:本地線程?

什麼是本地線程?

本地線程開玩笑的說:不要迷戀哥,哥只是個傳說。

其實ThreadLocal並非Thread at Local,而是LocalVariable in a Thread。

根據WikiPedia上的介紹,ThreadLocal其實是源於一項多線程技術,叫做Thread Local Storage,即執行緒區域儲存技術。不僅僅是Java ,在C++、C#、.NET、Python、Ruby、Perl等開發平台上,該技術都已經得以實現。

當使用ThreadLocal維護變數時,它會為每個使用該變數的線程提供獨立的變數副本。也就是說,他從根本上解決的是資源數量的問題 ,從而使得每個線程持有相對獨立的資源。這樣,當多個線程進行工作的時候,它們不需要糾結於同步的問題,於是效能便大大提升。但 資源的擴張帶來的是更多的空間消耗,ThreadLocal就是這樣一種利用空間來換取時間的解決方案。

說了這麼多,來看看如何正確使用ThreadLocal。

通過研究JDK文檔,我們知道,ThreadLocal中有幾個重要的方法:get()、set()、remove()、initailValue(),對應的含義分別是:

返回此線程局部變數的當前線程副本中的值、將此線程局部變數的當前線程副本中的值設定為指定值、移除此線程局部變數當前線程的 值、返回此線程局部變數的當前線程的“初始值”。

還記得我們在第三篇的上半節引出的那個例子嗎?幾個線程修改同一個Student對象中的age屬性。為了保證這幾個線程能夠工作正常, 我們需要對Student的對象進行同步。

下面我們對這個程式進行一點小小的改造,我們通過繼承Thread來實現多線程:

/**
  *
  * @author x-spirit
  */
public class ThreadDemo3 extends Thread{
     private ThreadLocal<Student> stuLocal = new ThreadLocal<Student>();
     public ThreadDemo3(Student stu){
         stuLocal.set(stu);
     }
     public static void main(String[] args) {
         Student stu = new Student();
         ThreadDemo3 td31 = new ThreadDemo3(stu);
         ThreadDemo3 td32 = new ThreadDemo3(stu);
         ThreadDemo3 td33 = new ThreadDemo3(stu);
         td31.start();
         td32.start();
         td33.start();
     }
     @Override
     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 = stuLocal.get();
         student.setAge(age);
         System.out.println("thread " + currentThreadName + " first  read age is:" +  student.getAge());
         try {
             Thread.sleep(5000);
         } catch (InterruptedException ex) {
             ex.printStackTrace();
         }
         System.out.println("thread " + currentThreadName + " second read age is:" + student.getAge ());
     }
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.