java 線程之對(duì)象的同步和異步(實(shí)例講解)
一、多線程環(huán)境下的同步與異步
同步:A線程要請(qǐng)求某個(gè)資源,但是此資源正在被B線程使用中,因?yàn)橥綑C(jī)制存在,A線程請(qǐng)求不到,怎么辦,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(); } }
觀察輸出結(jié)果:method1:th1 在3秒后 method2:th2 輸出,這是因?yàn)閙ethod2() 與 method1()都是同步方法,而線程thread1 與 thread2操作的是同一個(gè)對(duì)象th,所以thread2在執(zhí)行method2()方法時(shí),需要先獲得到th對(duì)象的鎖。
異步:A線程要請(qǐng)求某個(gè)資源,但是此資源正在被B線程使用中,因?yàn)闆]有同步機(jī)制存在,A線程仍然請(qǐng)求的到,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(); } }
觀察輸出結(jié)果:method1:th1 與 method2:th2 同時(shí)輸出,這是因?yàn)閙ethod2 沒有加同步控制,所以線程thread2在執(zhí)行method2()方法時(shí)不用去獲得執(zhí)行權(quán)限(對(duì)象鎖)。
二、數(shù)據(jù)的臟讀
我們?cè)谠O(shè)計(jì)業(yè)務(wù)的時(shí)候一定要考慮業(yè)務(wù)的整體性,不然就會(huì)出現(xiàn)數(shù)據(jù)一致性問題。
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(); } }
結(jié)果:get:name=LS passWorrd=123 set:name=LS passWorrd=456 由結(jié)果可知get的數(shù)據(jù)顯然有問題,這是因?yàn)閠hread線程在set的時(shí)候,main線程在執(zhí)行g(shù)et方法。想要避免這種情況,我們就要保證當(dāng)有線程在操作同一個(gè)對(duì)象的數(shù)據(jù)時(shí),就不然其他線程也同時(shí)操作該對(duì)象的數(shù)據(jù)。這個(gè)情況我們?cè)趃et方法上加 synchronized 關(guān)鍵字即可。
以上這篇java 線程之對(duì)象的同步和異步(實(shí)例講解)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java16新特性record類使用細(xì)節(jié)示例詳解
這篇文章主要為大家介紹了Java16新特性record類使用細(xì)節(jié)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09java的SimpleDateFormat線程不安全的幾種解決方案
但我們知道SimpleDateFormat是線程不安全的,處理時(shí)要特別小心,要加鎖或者不能定義為static,要在方法內(nèi)new出對(duì)象,再進(jìn)行格式化,本文就介紹了幾種方法,感興趣的可以了解一下2021-08-08javascript checkbox全選和反選的簡單實(shí)現(xiàn)
這篇文章主要介紹了javascript checkbox全選和反選的簡單實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2017-05-05Spring Cloud根據(jù)服務(wù)名獲取服務(wù)的ip端口問題
這篇文章主要介紹了Spring Cloud根據(jù)服務(wù)名獲取服務(wù)的ip端口,本篇示例我就以Nacos注冊(cè)中心為例了,下面是我注冊(cè)的兩個(gè)服務(wù),需要的朋友可以參考下2022-09-09Java實(shí)現(xiàn)兩人五子棋游戲(五) 判斷是否有一方勝出
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)兩人五子棋游戲,判斷是否有一方勝出,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03