熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Java多線程共享數據、同步、通信

2013-11-23 19:45:00  來源: Java高級技術 

  一線程共享數據

  a)繼承Thread那麼我們可以創建很多個這樣的類但是每個這樣的類都是相互不關聯的也就是說我們Thread類中的內容每個創建出來的類都有一份因此它不適合作為數據共享的線程來操作同時由於Java繼承的唯一性我們只能繼承一個對象

  b)使用runnable就可以解決唯一性和不能共享的問題(不是說使用runnable就解決了共享問題只是相對於創建Thread來說它可以算的上是共享了為了獲得更精確的共享問題它必須的使用線程同步操作)實現了runnable接口的類比較適合用作共享數據

  一個測試例子à證明runnable能實現數據共享thread不能

  Thread_thread一個繼承了Thread的線程

  Thread_runnable是一個時間了runnable的接口他們在run裡面有共同的方法

  for(int i=;i<;i++){

  if(ticket>){

  Systemoutprintln(ticket);

  ticket;

  }

  }

  thread_thread th=new thread_thread();

  thread_thread th=new thread_thread();

  thread_thread th=new thread_thread();

  thstart();

  thstart();

  thstart();

  輸入了三組

  因為創建的是三個對象每一個對象都擁有自己的一個備份

  將一個runnable作為參數實例化三個thread對象

  thread_runnable ru=new thread_runnable();

  Thread th=new Thread(ru);

  Thread th=new Thread(ru);

  Thread th=new Thread(ru);

  thstart();

  thstart();

  thstart();

  輸入了

  雖然說著不是完整意義上的數據共享但是相當於上述打印三組完整的數據來說它已經實現了數據共享我們從中也可以看到我們只創建了一個runnable對象(數據只產生了一份)它由三個Thread調用

  新建三個runnable對象分別給每一個thread傳遞

  Thread th=new Thread(new thread_runnable());

  Thread th=new Thread(new thread_runnable());

  Thread th=new Thread(new thread_runnable());

  thstart();

  thstart();

  thstart();

  打印結果是

  我們可以看到我們產生了三個runnable對象每一個都有自己的一份使用

  綜上所述只有將一個runnable對象作為參數傳遞給thread對象才能實現數據共享

  注意當我們創建一個Thread對象並多次調用start方法的時候系統是不會給你創建多個Thread線程的它只會運行那個唯一的Thread一次而已也就是說你運行了一次start方法之後再調用一個它的start方法是沒有意義的(那個Thread沒有結束的情況下)系統不會給你多次運行的

  二線程同步

  a)線程代碼塊(在代碼中添加Synchronized(對象){})

  iSynchronized(對象)每個對象都有個標志位當我們進入synchronized代碼塊中系統就讓這個對象的標志位變為就相當於給這個對象添加上了一把鎖當別的代碼運行到這個代碼塊的時候因為加了鎖所以不能進去當第一個程序它運行出去之後系統就會讓標志位變為相當於解鎖這樣別的代碼又可以訪問了從而實現同步(安全)操作

  ii當我們將我們的標志位對象放在run方法裡面定義的時候我們是不能實現同步的因為我們每次運行一個線程都將調用它的run方法從而每次都會創建一個新的標志位對象也就是說我們所有的run方法都含有自己的一個標志位對象因此不能實現加鎖的過程一般都是放在runnable接口中進行定義的

  b)線程方法(在代碼的方法申明中public和void之間添加synchronized)

  i每次只能有一個線程調用這個同步方法而且每次這個方法都得運行完這就是同步代碼方法

  ii同步方法默認使用的是this來作為標志對象位的這個this就是我們的當前類

  c)注意

  i當一個同步代碼塊和一個同步代碼方法使用的不是同一個對象作為標志位的時候它們就不會實現同步這也就是數當兩個同步代碼塊不使用同一個對象作為標志位那他們就不能實現同步

  ii調用線程的Start方法的時候並沒有真正的運行這個代碼而只是說這個代碼已經准備就緒有運行的可能

  三線程通信

  a)當我們的代碼中使用了synchronized(對象)同步代碼塊的時候如果我們想實現線程通信也就是如果我們想使用waitnotify或者notifyall時我們必須在靜態代碼塊中使用對象wait()對象notify()對象notifyAll()來通信不然的話講會報Illegal的錯誤

  b)Notify是喚醒同一監視器下(相當於同一個標志位對象)的第一個wait線程而notifyall是喚醒所有的處於同一監視器下的(同一標志位對象)的線程


From:http://tw.wingwit.com/Article/program/Java/gj/201311/27394.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.