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

歡迎訪問 生活随笔!

生活随笔

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

java

Java多线程(2)—线程同步

發布時間:2025/3/20 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程(2)—线程同步 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

介紹了線程的基本概念和方法,終于進入到上一章中介紹的取款問題了。回顧下在支付寶和微信上做了綁定卡之后,查詢為3000,此時在支付寶和微信的均取出2000,此時銀行卡變成了-1000

?那上述取款如何實現呢?

package blog;public class TestAccount {public static void main(String[] args) {Account account = new Account();//多線程對象User u_weixin = new User(account, 2000);User u_zhifubao = new User(account, 2000);Thread weixin = new Thread(u_weixin,"微信賬戶");Thread zhifubao = new Thread(u_zhifubao,"支付寶賬戶");weixin.start();zhifubao.start();} }class Account{public static int money = 3000;//全局變量,共享數據public void takeMoney(int m) {String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}} }class User implements Runnable{Account account;int money;public User(Account account,int money) {// TODO Auto-generated constructor stubthis.account = account;this.money = money;}@Overridepublic void run() {// TODO Auto-generated method stubaccount.takeMoney(money);} }

查看輸出結果

多線程調用方法時,存在上述問題。線程共享資源時,一個線程在執行方法沒有完畢時,另一個線程開始執行這個方法,導致共享數據出錯。那如何解決,自然就是讓一個線程先執行完成,在執行過程中拒絕其他線程參與執行。就是一個線程一個線程的依次完成執行。

1、方法加入synchronized同步鎖

通過在方法上加入關鍵字synchronized來處理。public?synchronized void takeMoney();因此將上述代碼中的takeMoney進行改造如下:

class Account{public static int money = 3000;public synchronized void takeMoney(int m) {String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}} }

此時查看輸出結果如下:

?

注意:在普通方法上加同步鎖synchronized,鎖的是整個對象,不是某一個方法。如何理解這句話呢,我們將上述的方法進行改造。

1.將takeMoney復制一份命名為takeMoney1

2.將run中加入線程名稱判斷

package blog;public class TestAccount {public static void main(String[] args) {Account account = new Account();//多線程對象User u_weixin = new User(account, 2000);User u_zhifubao = new User(account, 2000);Thread weixin = new Thread(u_weixin,"微信賬戶");Thread zhifubao = new Thread(u_zhifubao,"支付寶賬戶");weixin.start();zhifubao.start();} }class Account{public static int money = 3000;public synchronized void takeMoney(int m) {String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}}public synchronized void takeMoney1(int m) {String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}}}class User implements Runnable{Account account;int money;public User(Account account,int money) {// TODO Auto-generated constructor stubthis.account = account;this.money = money;}@Overridepublic void run() {// TODO Auto-generated method stub // account.takeMoney(money);if (Thread.currentThread().getName() == "微信") {account.takeMoney(money);}else {account.takeMoney1(money);}} }

輸出結果:

?發現輸出結果依然能正確輸出,這就是所謂的鎖住的是對象,因為我們定義了一個賬戶對象account。作為對比,新建兩個對象,則輸出結果如下所示:

綜上所述,所以說synchronized鎖住的是對象方法。不同的對象是不同的鎖,因此線程使用不同對象調用此方法依然有資源共享的問題。

//將Account中的takeMoney進行如下改造public static synchronized void takeMoney2(int m) {String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}}

?將User中的方法調整如下

class User implements Runnable{Account account;int money;public User(Account account,int money) {// TODO Auto-generated constructor stubthis.account = account;this.money = money;}@Overridepublic void run() {account.takeMoney2(money);} }

此時查看輸出結果

?

同static屬性和方法是共享的一樣,這里加入static synchronized 表示為類的屬性/方法。

2.代碼塊加入同步鎖

新增一個takeMoney4方法,并在代碼塊加入同步鎖synchronized

package blog;public class TestAccount {public static void main(String[] args) {Account account = new Account();Account account1 = new Account();//多線程對象User u_weixin = new User(account, 2000);User u_zhifubao = new User(account1, 2000);Thread weixin = new Thread(u_weixin,"微信賬戶");Thread zhifubao = new Thread(u_zhifubao,"支付寶賬戶");weixin.start();zhifubao.start();} }class Account{public static int money = 3000;public synchronized void takeMoney(int m) {String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}}/*** 靜態方法加synchronized,對所有對象都是同一個鎖* @param m*/public static synchronized void takeMoney2(int m) {String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}}public void takeMoney3(int m) {synchronized(this){//表示當前對象的代碼被加入了synchronized同步鎖,this表示當前對象String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}}}public void takeMoney4(int m) {synchronized(this){//表示當前對象的代碼被加入了synchronized同步鎖,this表示當前對象String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}}}}class User implements Runnable{Account account;int money;public User(Account account,int money) {// TODO Auto-generated constructor stubthis.account = account;this.money = money;}@Overridepublic void run() {// TODO Auto-generated method stub // account.takeMoney(money);if (Thread.currentThread().getName() == "微信") {account.takeMoney3(money);}else {account.takeMoney4(money);}// account.takeMoney2(money);} }

依然是用的是兩個對象進行調用,輸出結果如下:

?

那如果使用的是一個對象呢?

//多線程對象User u_weixin = new User(account, 2000);User u_zhifubao = new User(account, 2000);

輸出如下:

這里的輸出結果和使用方法同步鎖一樣,存在不同的對象出現共享資源有限錯誤的情況。那同一個對象加入相同的鎖,不同的對象加入不同的鎖如何實現呢,可以通過對方法傳入的對象加入synchronized同步鎖,如下所示:

public void takeMoney5(int m,Account a) {synchronized(a){//表示當前對象的代碼被加入了synchronized同步鎖,this表示當前對象String name = Thread.currentThread().getName();if (m > money) {System.out.println(name + "操作,賬戶金額不足:"+money);}else {System.out.println(name + "操作,賬戶原有金額:"+money);System.out.println(name + "操作,取款金額:" + m);money = money - m;System.out.println(name + "操作,取款后的余額:" + money);}}} class User implements Runnable{Account account;int money;public User(Account account,int money) {// TODO Auto-generated constructor stubthis.account = account;this.money = money;}@Overridepublic void run() { account.takeMoney5(money,account);} }

如果是相同的對象,則輸出:

如果是不同的對象,則輸出:

?

因此可有如下結論:

  • 普通方法加入同步鎖,所得是當前方法對應的對象,當前對象的所有的加了同步鎖的方法共用一個同步鎖
  • 靜態方法方法加入同步鎖,所有對象公用一個同步鎖
  • 代碼塊加入同,如果是synchronized(this)形式,所有當前的對象的synchronized(this)同步的代碼使用同一個鎖,如果是synchronized(obj)不同的對象使用的不同的鎖
  • ?

    總結

    以上是生活随笔為你收集整理的Java多线程(2)—线程同步的全部內容,希望文章能夠幫你解決所遇到的問題。

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