首頁 >Java >java教程 >Java執行緒中關於物件的同步與非同步的實例分析

Java執行緒中關於物件的同步與非同步的實例分析

黄舟
黄舟原創
2017-07-20 14:16:022068瀏覽

下面小編就為大家帶來一篇java 執行緒之物件的同步與非同步(實例講解)。小編覺得蠻不錯的,現在就分享給大家,也給大家做個參考。一起跟著小編過來看看吧

一、多執行緒環境下的同步與非同步

##同步: A執行緒要請求某個資源,但是此資源正在被B執行緒使用中,因為同步機制存在,A執行緒請求不到,怎麼辦,A執行緒只能等待下去。


package com.jalja.org.thread.demo01;

public class Thread02 {
 public synchronized void method1(){
  System.out.println("method1:"+Thread.currentThread().getName());
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 public synchronized void method2(){
  System.out.println("method2:"+Thread.currentThread().getName());
 }
 public static void main(String[] args) {
  final Thread02 th=new Thread02();
  Thread thread1=new Thread(new Runnable() {
   public void run() {
    th.method1();
   }
  },"th1");
  
  Thread thread2=new Thread(new Runnable() {
   public void run() {
    th.method2();
   }
  },"th2");
  
  thread1.start();
  thread2.start();
 }
}

觀察輸出結果:method1:th1 在3秒後method2:th2 輸出,這是因為method2() 與method1()都是同步方法,而執行緒thread1與thread2操作的是同一個物件th,所以thread2在執行method2()方法時,需要先取得th物件的鎖。

非同步:A執行緒要請求某個資源,但是此資源正在被B執行緒使用中,因為沒有同步機制存在,A執行緒仍然請求的到,A線程無需等待。


package com.jalja.org.thread.demo01;

public class Thread02 {
 public synchronized void method1(){
  System.out.println("method1:"+Thread.currentThread().getName());
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 public void method2(){
  System.out.println("method2:"+Thread.currentThread().getName());
 }
 public static void main(String[] args) {
  final Thread02 th=new Thread02();
  Thread thread1=new Thread(new Runnable() {
   public void run() {
    th.method1();
   }
  },"th1");
  
  Thread thread2=new Thread(new Runnable() {
   public void run() {
    th.method2();
   }
  },"th2");
  
  thread1.start();
  thread2.start();
 }
}

觀察輸出結果:method1:th1 與method2:th2 同時輸出,這是因為method2 沒有加同步控制,所以執行緒thread2在執行method2()方法時不用去獲得執行權限(物件鎖定)。

二、資料的髒讀

我們在設計業務的時候一定要考慮業務的整體性,不然就會出現資料一致性問題。


package com.jalja.org.thread.demo01;

public class Thread03 {
 private String name="zs";
 private String passWorrd="123";
 public synchronized void setValue(String name,String passWord){
  this.name=name;
  try {
   Thread.sleep(2000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  this.passWorrd=passWord;
  System.out.println("set:name="+this.name +" passWorrd="+this.passWorrd);
 }
 public void getValue(){
  System.out.println("get:name="+this.name +" passWorrd="+this.passWorrd);
 }
 public static void main(String[] args) throws InterruptedException {
  final Thread03 th=new Thread03();
  Thread thread=new Thread(new Runnable() {
   public void run() {
    th.setValue("LS", "456");
   }
  });
  thread.start();
  Thread.sleep(100);
  th.getValue();
 }
}

結果:#get:name=LS  passWorrd=123     set:name=LS  passWorrd=456      set:name=LS  passWorrd=456  的資料顯然有問題,這是因為thread執行緒​​在set的時候,main執行緒在執行get方法。想要避免這種情況,我們就要確保當有執行緒在操作同一個物件的資料時,就不然其他執行緒也同時操作該物件的資料。這個情況我們在get方法上加 synchronized 關鍵字即可。

以上是Java執行緒中關於物件的同步與非同步的實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn