java 線程之對象的同步和異步(實例講解)
一、多線程環(huán)境下的同步與異步
同步: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();
}
}
觀察輸出結(jié)果:method1:th1 在3秒后 method2:th2 輸出,這是因為method2() 與 method1()都是同步方法,而線程thread1 與 thread2操作的是同一個對象th,所以thread2在執(zhí)行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();
}
}
觀察輸出結(jié)果:method1:th1 與 method2:th2 同時輸出,這是因為method2 沒有加同步控制,所以線程thread2在執(zhí)行method2()方法時不用去獲得執(zhí)行權(quán)限(對象鎖)。
二、數(shù)據(jù)的臟讀
我們在設(shè)計業(yè)務(wù)的時候一定要考慮業(yè)務(wù)的整體性,不然就會出現(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ù)顯然有問題,這是因為thread線程在set的時候,main線程在執(zhí)行g(shù)et方法。想要避免這種情況,我們就要保證當有線程在操作同一個對象的數(shù)據(jù)時,就不然其他線程也同時操作該對象的數(shù)據(jù)。這個情況我們在get方法上加 synchronized 關(guān)鍵字即可。
以上這篇java 線程之對象的同步和異步(實例講解)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java的SimpleDateFormat線程不安全的幾種解決方案
但我們知道SimpleDateFormat是線程不安全的,處理時要特別小心,要加鎖或者不能定義為static,要在方法內(nèi)new出對象,再進行格式化,本文就介紹了幾種方法,感興趣的可以了解一下2021-08-08
javascript checkbox全選和反選的簡單實現(xiàn)
這篇文章主要介紹了javascript checkbox全選和反選的簡單實現(xiàn)的相關(guān)資料,需要的朋友可以參考下2017-05-05
Spring Cloud根據(jù)服務(wù)名獲取服務(wù)的ip端口問題
這篇文章主要介紹了Spring Cloud根據(jù)服務(wù)名獲取服務(wù)的ip端口,本篇示例我就以Nacos注冊中心為例了,下面是我注冊的兩個服務(wù),需要的朋友可以參考下2022-09-09
Java實現(xiàn)兩人五子棋游戲(五) 判斷是否有一方勝出
這篇文章主要為大家詳細介紹了Java實現(xiàn)兩人五子棋游戲,判斷是否有一方勝出,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03

