歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java多線程之synchronized

這裡通過三個測試類闡述了synchronized應用的不同場景

 

首先是最基本的synchronized Method的使用

  1. package com.jadyer.thread.sync; 
  2.  
  3. /** 
  4.  * Synchronized Method Test 
  5.  * @see =================================================================================================== 
  6.  * @see 概述:Java中的每個對象都有一個鎖(lock)或者叫做監視器(monitor) 
  7.  * @see 說明:當synchronized關鍵字修飾一個方法時,則該方法為同步方法 
  8.  * @see      當某個線程訪問某個對象的synchronized方法時,則表示將該對象上鎖 
  9.  * @see      此時其它的任何線程,均無法訪問該對象中的任何一個synchronized方法(但允許訪問該對象中的非synchronized方法) 
  10.  * @see      直到該線程所訪問的synchronized方法執行完畢(或者拋出了異常)之後,該對象的鎖才會被釋放 
  11.  * @see      此時其它的任何線程,才被允許訪問該synchronized方法,或者是該對象中的其它synchronized方法 
  12.  * @see =================================================================================================== 
  13.  * @see 總結:如果一個對象有多個synchronized方法,某一時刻某個線程已經執行了該對象中的某一個synchronized方法 
  14.  * @see      那麼在該方法沒有執行完畢之前,其它線程是無法訪問該對象中的,包括該方法在內的,任何一個synchronized方法 
  15.  * @see      重點在於判斷Synchronized鎖的是誰。如果該方法是靜態的,則鎖Class對象,否則鎖的就是當前對象 
  16.  * @see =================================================================================================== 
  17.  * @see 補充:1)這只是針對多個線程操作同一個類的同一個對象的情況。www.linuxidc.com若多個線程操作同一個類的不同對象,則不存在這種情況 
  18.  * @see      2)Java中的volatile變量也可以看作是一種"程度較輕的synchronized" 
  19.  * @see        關於volatile的更多信息,請參考http://www.ibm.com/developerworks/cn/java/j-jtp06197.html 
  20.  * @see 備注:實際項目中,用到的更多的還是JDK5.0開始推出的Java並發包,即java.util.concurrent包裡面的工具類 
  21.  * @see      java.util.concurrent可以非常細粒度的實現並發。比如線程訪問到了一個已被鎖的對象,它可以讓這個線程等到10秒 
  22.  * @see      10秒後如果該對象仍未被解鎖,那麼就可以返回給用戶超時的提示等,而如果使用synchronized則是無法這麼精確控制的 
  23.  * @see =================================================================================================== 
  24.  * @see 注意:1)當synchronized方法執行完或者發生異常時,會自動釋放鎖 
  25.  * @see      2)被synchronized保護的數據應該是private的,否則也就沒必要去通過方法來訪問這個public的數據了 
  26.  * @see =================================================================================================== 
  27.  * @author 宏宇 
  28.  * @create Feb 21, 2012 5:29:39 PM 
  29.  */ 
  30. public class SynchronizedTest { 
  31.     public static void main(String[] args) { 
  32.         Bank bank = new Bank(); 
  33.          
  34.         Thread tt11 = new Thread(new ThreadRMB(bank)); 
  35.          
  36.         //new一個新的Bank對象。此時存在兩個Bank對象,並且它們屬於同一個類的不同的對象  
  37.         //如要驗證多個線程操作同一個類的不同的對象的synchronized方法,只需取消注釋該行代碼即可  
  38.         //bank = new Bank();  
  39.          
  40.         Thread tt22 = new Thread(new ThreadDollar(bank)); 
  41.          
  42.         tt11.start(); 
  43.         tt22.start(); 
  44.     } 
  45.  
  46.  
  47. class ThreadRMB implements Runnable{ 
  48.     private Bank bank; 
  49.     public ThreadRMB(Bank bank){ 
  50.         this.bank = bank; 
  51.     } 
  52.     @Override 
  53.     public void run() { 
  54.         bank.getRMB(); 
  55.     } 
  56.  
  57.  
  58. class ThreadDollar implements Runnable{ 
  59.     private Bank bank; 
  60.     public ThreadDollar(Bank bank){ 
  61.         this.bank = bank; 
  62.     } 
  63.     @Override 
  64.     public void run() { 
  65.         bank.getDollar(); 
  66.     } 
  67.  
  68.  
  69. class Bank{ 
  70.     public synchronized void getRMB(){ 
  71.         for(int i=0; i<20; i++){ 
  72.             try { 
  73.                 Thread.sleep((long)(Math.random()*1000)); 
  74.             } catch (InterruptedException e) { 
  75.                 e.printStackTrace(); 
  76.             } 
  77.             System.out.println(Thread.currentThread().getName() + ":" + i); 
  78.         } 
  79.     } 
  80.      
  81.     public synchronized void getDollar(){ 
  82.         for(int i=0; i<20; i++){ 
  83.             try { 
  84.                 Thread.sleep((long)(Math.random()*1000)); 
  85.             } catch (InterruptedException e) { 
  86.                 e.printStackTrace(); 
  87.             } 
  88.             System.out.println(Thread.currentThread().getName() + ":" + i); 
  89.         } 
  90.     } 
Copyright © Linux教程網 All Rights Reserved