歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java多線程之synchronized

Java多線程之synchronized

日期:2017/3/1 10:26:16   编辑:Linux編程

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

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

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