程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java多線程編程中的線程同步Synchronized

Java多線程編程中的線程同步Synchronized

編輯:關於JAVA

Synchronized,顧名思義,代表線程同步。那麼,在Java編程中如何使用它呢?

  我們首先來看這樣一個情況:對於同一個變量synDemo,我們分別在2個不同的線程中調用synDemo.synMethord1()與synDemo.synMethord2()。


 package com.cnblogs.gpcuster;/** * * @author Aaron.Guo * */
  public class Tester {public static void main(String[] args) {final SynDemo synDemo = new SynDemo();Thread thread1 = new Thread() {@Overridepublic void run() {// TODO Auto-generated method stub 
  super.run();synDemo.synMethord1();}};Thread thread2 = new Thread() {@Overridepublic void run() {// TODO Auto-generated method stub 
  super.run();synDemo.synMethord2();}};thread1.start();thread2.start();while (true) {try {Thread.sleep(1000);System.out.println("main");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  } 
  我們的SynDemo是這樣定義的: 
  package com.cnblogs.gpcuster;/** * * @author Aaron.Guo * */
  public class SynDemo{public void synMethord1() {while(true) {try {Thread.sleep(1000);System.out.println("synMethord1");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  public void synMethord2() {while(true) {try {Thread.sleep(1000);System.out.println("synMethord2");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  }

  我們的SynDemo對象沒有任何特殊的定義,所以運行起來以後的情況如下:


  synMethord2 
  synMethord1 
  main 
  synMethord2 
  synMethord1 
  main 
  synMethord2 
  synMethord1

  接下來,我們給synMethord1添加上synchronized聲明,運行情況還是與上次一樣,因為我們只有一個線程在調用synMethord1的方法。

  我們給synMethord2也添加上synchronized聲明,SynDemo對象的代碼修改為:

 


 package com.cnblogs.gpcuster;/** * * @author Aaron.Guo * */
  public class SynDemo{public synchronized void synMethord1() {while(true) {try {Thread.sleep(1000);System.out.println("synMethord1");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  public synchronized void synMethord2() {while(true) {try {Thread.sleep(1000);System.out.println("synMethord2");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  }

  這個時候,我們再運行程序,結果就不一樣了:


 main 
  synMethord1 
  main 
  synMethord1 
  main 
  synMethord1

  我們發現,對於SynDemo對象,只有synMethord1運行了,而synMethord2卻沒有運行。這是應為在方法級別的synchronized聲明將lock這個類對象的當前實例。所以在synMethord1運行結束unlock之前,當前實例是無法運行synMethord2的。這種方法級別的synchronized聲明和以下的做法是等同的:


 package com.cnblogs.gpcuster;/** * * @author Aaron.Guo * */
  public class SynDemo {public void synMethord1() {synchronized (this) {while (true) {try {Thread.sleep(1000);System.out.println("synMethord1");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  } 
  public synchronized void synMethord2() {synchronized (this) {while (true) {try {Thread.sleep(1000);System.out.println("synMethord2");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  } 
  }

  運行程序,結果與上次相同。

  如果我們希望分別同步2個方法該如何處理?可以參考這個實現:


 package com.cnblogs.gpcuster;/** * * @author Aaron.Guo * */
  public class SynDemo {private Object flag1 = new Object();private Object flag2 = new Object();public void synMethord1() {synchronized (flag1) {while (true) {try {Thread.sleep(1000);System.out.println("synMethord1");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  } 
  public void synMethord2() {synchronized (flag2) {while (true) {try {Thread.sleep(1000);System.out.println("synMethord2");} catch (InterruptedException e) {// TODO Auto-generated catch block 
  e.printStackTrace(); 
  } 
  } 
  } 
  } 
  }

  運行程序,結果如我們預期:


    main 
  synMethord2 
  synMethord2 
  main 
  synMethord1 
  main 
  synMethord1 
  synMethord2

  關於Synchronized還有一些其他的話題,如static的問題,繼承的問題,與volatile搭配使用等等,在網上都有很詳細的說明,這裡就不重復介紹了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved