日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java之线程安全的几种方式

發布時間:2025/4/16 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java之线程安全的几种方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、使用synchronized重寫run方法
  • 二、使用synchronized修飾方法(同步方法)
  • 三、使用同步鎖Lock

一、使用synchronized重寫run方法

在多線程中,若不使用synchronzied保證線程安全,則可能會應為線程的切換帶來一些數據異常
如銀行取錢

public class Thread_safe_acount {private String accountNo;private double balance;public Thread_safe_acount( ){}public Thread_safe_acount(String accountNo, double balance) {this.accountNo = accountNo;this.balance = balance;}public void setAccountNo(String accountNo) {this.accountNo = accountNo;}public void setBalance(double balance) {this.balance = balance;}public String getAccountNo() {return accountNo;}public double getBalance() {return balance;}// 重寫hashCode@Overridepublic int hashCode() {return accountNo.hashCode();}@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj!=null && obj.getClass()==Thread_safe_acount.class ){Thread_safe_acount target = (Thread_safe_acount) obj;return(target.getAccountNo().equals(accountNo));}return false;}} public class Thread_safe_main extends Thread {private Thread_safe_acount account;private double need;public Thread_safe_main() {}public Thread_safe_main(String name, Thread_safe_acount account, double need) {super(name);this.account = account;this.need = need;}@Overridepublic void run() {if (account.getBalance() >= need) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}account.setBalance(account.getBalance() - need);System.out.println("客戶" + getName() + "取錢成功,當前賬戶余額:" + (account.getBalance()));} else if (account.getBalance() < need) {System.out.println("當前余額不足!");}}public static void main(String[] args) {for (int i = 0; i < 20; i++) {Thread_safe_acount tsa1 = new Thread_safe_acount("001", 100);Thread_safe_main tsm1 = new Thread_safe_main("張三豐", tsa1, 100);Thread_safe_main tsm2 = new Thread_safe_main("張四豐", tsa1, 100);tsm1.start();tsm2.start();}}}

運行結果如下:

解決代碼(使用synchronized重寫run)

public class Thread_Truesafe_main extends Thread {private Thread_safe_acount account;private double need;public Thread_Truesafe_main() {}public Thread_Truesafe_main(String name, Thread_safe_acount account, double need) {super(name);this.account = account;this.need = need;}@Overridepublic void run() {synchronized (account) {if (account.getBalance() >= need) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}account.setBalance(account.getBalance() - need);System.out.println("客戶" + getName() + "取錢成功,當前賬戶余額:" + (account.getBalance()));} else if (account.getBalance() < need) {System.out.println("當前余額不足!");}}}public static void main(String[] args) {// for (int i = 0; i < 20; i++) {Thread_safe_acount tsa1 = new Thread_safe_acount("001", 100);Thread_Truesafe_main tsm1 = new Thread_Truesafe_main("張三豐", tsa1, 100);Thread_Truesafe_main tsm2 = new Thread_Truesafe_main("張四豐", tsa1, 100);tsm1.start();tsm2.start();// }}}

運行結果:

二、使用synchronized修飾方法(同步方法)

public class Thread_safe_acount_Synchronized {private String accountNo;private double balance;public Thread_safe_acount_Synchronized( ){}public Thread_safe_acount_Synchronized(String accountNo, double balance) {this.accountNo = accountNo;this.balance = balance;}public void setAccountNo(String accountNo) {this.accountNo = accountNo;}public String getAccountNo() {return accountNo;}public double getBalance() {return balance;}public synchronized void draw(double need) {if (balance >= need) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}balance=balance - need;System.out.println("客戶" + Thread.currentThread().getName() + "取錢成功,當前賬戶余額:" + balance);} else if (balance < need) {System.out.println("當前余額不足!");}}// 重寫hashCode@Overridepublic int hashCode() {return accountNo.hashCode();}@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj!=null && obj.getClass()==Thread_safe_acount_Synchronized.class ){Thread_safe_acount_Synchronized target = (Thread_safe_acount_Synchronized) obj;return(target.getAccountNo().equals(accountNo));}return false;}}

測試類:

public class Thread_safe_main_synchronized extends Thread {private Thread_safe_acount_Synchronized account;private double need;public Thread_safe_main_synchronized() {}public Thread_safe_main_synchronized(String name, Thread_safe_acount_Synchronized account, double need) {super(name);this.account = account;this.need = need;}@Overridepublic void run() {account.draw(need);}public static void main(String[] args) {// for (int i = 0; i < 20; i++) {Thread_safe_acount_Synchronized tsa1 = new Thread_safe_acount_Synchronized("001", 100);Thread_safe_main_synchronized tsm1 = new Thread_safe_main_synchronized("張三豐", tsa1, 100);Thread_safe_main_synchronized tsm2 = new Thread_safe_main_synchronized("張四豐", tsa1, 100);tsm1.start();tsm2.start();// }}}

執行結果:

優點:

  • 更符合面向對象規劃
  • 領域驅動設計模式(DDD,Domain Driven Design)認為每個類都應該是完備的領域對象,比如account類除了具備基本屬性外,還應有轉賬、取錢等相應的與賬戶相關的方法。從而保證對象的完整性和一致性。

三、使用同步鎖Lock

import java.util.concurrent.locks.ReentrantLock;public class Thread_safe_acount_Lock {private final ReentrantLock lock =new ReentrantLock();private String accountNo;private double balance;public Thread_safe_acount_Lock( ){}public Thread_safe_acount_Lock(String accountNo, double balance) {this.accountNo = accountNo;this.balance = balance;}public void setAccountNo(String accountNo) {this.accountNo = accountNo;}public String getAccountNo() {return accountNo;}public double getBalance() {return balance;}public void draw(double need){lock.lock();try{if (balance >= need) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}balance=balance - need;System.out.println("客戶" + Thread.currentThread().getName() + "取錢成功,當前賬戶余額:" + balance);} else if (balance < need) {System.out.println("當前余額不足!");}} finally {lock.unlock();}}// 重寫hashCode@Overridepublic int hashCode() {return accountNo.hashCode();}@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj!=null && obj.getClass()==Thread_safe_acount_Lock.class ){Thread_safe_acount_Lock target = (Thread_safe_acount_Lock) obj;return(target.getAccountNo().equals(accountNo));}return false;}}

測試代碼:

public class Thread_safe_main_Lock extends Thread {private Thread_safe_acount_Lock account;private double need;public Thread_safe_main_Lock() {}public Thread_safe_main_Lock(String name, Thread_safe_acount_Lock tsa1, double need) {super(name);this.account = tsa1;this.need = need;}@Overridepublic void run() {account.draw(need);}public static void main(String[] args) {// for (int i = 0; i < 20; i++) {Thread_safe_acount_Lock tsa1 = new Thread_safe_acount_Lock("001", 100);Thread_safe_main_Lock tsm1 = new Thread_safe_main_Lock("張三豐", tsa1, 100);Thread_safe_main_Lock tsm2 = new Thread_safe_main_Lock("張四豐", tsa1, 100);tsm1.start();tsm2.start();// }}}

結果:

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的Java之线程安全的几种方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。