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)闆](méi)有同步機(jī)制存在,A線程仍然請(qǐng)求的到,A線程無(wú)需等待。
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 沒(méi)有加同步控制,所以線程thread2在執(zhí)行method2()方法時(shí)不用去獲得執(zhí)行權(quán)限(對(duì)象鎖)。
二、數(shù)據(jù)的臟讀
我們?cè)谠O(shè)計(jì)業(yè)務(wù)的時(shí)候一定要考慮業(yè)務(wù)的整體性,不然就會(huì)出現(xiàn)數(shù)據(jù)一致性問(wèn)題。
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ù)顯然有問(wèn)題,這是因?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í)例講解)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java16新特性record類(lèi)使用細(xì)節(jié)示例詳解
這篇文章主要為大家介紹了Java16新特性record類(lèi)使用細(xì)節(jié)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
java的SimpleDateFormat線程不安全的幾種解決方案
但我們知道SimpleDateFormat是線程不安全的,處理時(shí)要特別小心,要加鎖或者不能定義為static,要在方法內(nèi)new出對(duì)象,再進(jìn)行格式化,本文就介紹了幾種方法,感興趣的可以了解一下2021-08-08
javascript checkbox全選和反選的簡(jiǎn)單實(shí)現(xiàn)
這篇文章主要介紹了javascript checkbox全選和反選的簡(jiǎn)單實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2017-05-05
Spring Cloud根據(jù)服務(wù)名獲取服務(wù)的ip端口問(wèn)題
這篇文章主要介紹了Spring Cloud根據(jù)服務(wù)名獲取服務(wù)的ip端口,本篇示例我就以Nacos注冊(cè)中心為例了,下面是我注冊(cè)的兩個(gè)服務(wù),需要的朋友可以參考下2022-09-09
Java實(shí)現(xiàn)兩人五子棋游戲(五) 判斷是否有一方勝出
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)兩人五子棋游戲,判斷是否有一方勝出,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03

