當前位置:編程學習大全網 - 源碼下載 - 淺談Java多線程的同步問題

淺談Java多線程的同步問題

 多線程的同步依靠的是對象鎖機制 synchronized關鍵字的背後就是利用了封鎖來實現對***享資源的互斥訪問

 下面以壹個簡單的實例來進行對比分析 實例要完成的工作非常簡單 就是創建 個線程 每個線程都打印從 到 這 個數字 我們希望線程之間不會出現交叉亂序打印 而是順序地打印

 先來看第壹段代碼 這裏我們在run()方法中加入了synchronized關鍵字 希望能對run方法進行互斥訪問 但結果並不如我們希望那樣 這是因為這裏synchronized鎖住的是this對象 即當前運行線程對象本身 代碼中創建了 個線程 而每個線程都持有this對象的對象鎖 這不能實現線程的同步

 代碼 package vista; class MyThread implements java lang Runnable { private int threadId;

 public MyThread(int id) {? this threadId = id; }

 @Override public synchronized void run() {? for (int i = ; i < ; ++i) {? System out println( Thread ID: + this threadId + : + i);? } } }

 public class ThreadDemo { /**? * @param args? * @throws InterruptedException? */ public static void main(String[] args) throws InterruptedException {? for (int i = ; i < ; ++i) {? new Thread(new MyThread(i)) start();? Thread sleep( );? } } }

 從上述代碼段可以得知 要想實現線程的同步 則這些線程必須去競爭壹個唯壹的***享的對象鎖

 基於這種思想 我們將第壹段代碼修改如下所示 在創建啟動線程之前 先創建壹個線程之間競爭使用的Object對象 然後將這個Object對象的引用傳遞給每壹個線程對象的lock成員變量 這樣壹來 每個線程的lock成員都指向同壹個Object對象 我們在run方法中 對lock對象使用synchronzied塊進行局部封鎖 這樣就可以讓線程去競爭這個唯壹的***享的對象鎖 從而實現同步

 代碼 package vista;

 class MyThread implements java lang Runnable { private int threadId; private Object lock;

 public MyThread(int id Object obj) {? this threadId = id;? this lock = obj; }

 @Override public void run() {? synchronized (lock) {? for (int i = ; i < ; ++i) { System out println( Thread ID: + this threadId + : + i);? }? } } }

 public class ThreadDemo { /**? * @param args? * @throws InterruptedException? */ public static void main(String[] args) throws InterruptedException {? Object obj = new Object();? for (int i = ; i < ; ++i) {? new Thread(new MyThread(i obj)) start();? Thread sleep( );? } } }

 從第二段代碼可知 同步的關鍵是多個線程對象競爭同壹個***享資源即可 上面的代碼中是通過外部創建***享資源 然後傳遞到線程中來實現 我們也可以利用類成員變量被所有類的實例所***享這壹特性 因此可以將lock用靜態成員對象來實現 代碼如下所示

 代碼 package vista;

 class MyThread implements java lang Runnable { private int threadId; private static Object lock = new Object();

 public MyThread(int id) {? this threadId = id; }

 @Override public void run() {? synchronized (lock) {? for (int i = ; i < ; ++i) { System out println( Thread ID: + this threadId + : + i);? }? } } }

 public class ThreadDemo { /**? * @param args? * @throws InterruptedException? */ public static void main(String[] args) throws InterruptedException {? for (int i = ; i < ; ++i) {? new Thread(new MyThread(i)) start();? Thread sleep( );? } } }

 再來看第壹段代碼 實例方法中加入sychronized關鍵字封鎖的是this對象本身 而在靜態方法中加入sychronized關鍵字封鎖的就是類本身 靜態方法是所有類實例對象所***享的 因此線程對象在訪問此靜態方法時是互斥訪問的 從而可以實現線程的同步 代碼如下所示

 代碼 package vista;

 class MyThread implements java lang Runnable { private int threadId;

 public MyThread(int id) {? this threadId = id; }

 @Override public void run() {? taskHandler(this threadId); }

 private static synchronized void taskHandler(int threadId) {? for (int i = ; i < ; ++i) {? System out println( Thread ID: + threadId + : + i);? } } }

lishixinzhi/Article/program/Java/gj/201311/27441

  • 上一篇:數學建模 模擬多種情況
  • 下一篇:有關在zen-cart程序中嵌套模板問題
  • copyright 2024編程學習大全網