下面小編就為大家帶來一篇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中文網其他相關文章!