同步代碼塊應用之取錢問題、線程安全問題之線程同步機制(同步函數)

1、同步代碼塊經典實例: 
一、需求:一個銀行帳戶5000塊,兩夫妻一個拿着存摺,一個拿着卡,開始取錢比賽,每次只能取一千塊,要求不許出現線程安全問題。安全

二、目的:該程序是否有安全問題,若是有,如何解決? 
多線程

三、如何找問題: 
1)明確哪些代碼是多線程運行代碼。 
2)明確共享數據。 
3)明確多線程運行代碼中哪些語句是操做共享數據的。函數

四、代碼解決: 
方式一: 

方式二(正確方法):this

package sram.thread;

public class BankThread extends Thread{
    static int money = 5000;
    public BankThread(){

    }
    public BankThread(String name){
        super(name);
    }
    public void run() {
        while(true){
            synchronized("鎖"){
                if(money>0){
                    System.out.println(currentThread().getName()+
                        "取了1000元,還剩"+(money-1000)+"元");
                    money-=1000;
                }
            }
        }
    }

    public static void main(String args[]){
        BankThread user1 = new BankThread("老公");
        BankThread user2 = new BankThread("老婆");
        user1.start();
        user2.start();
    }
}

2、同步函數: 
一、同步函數定義:同步函數就是使用synchronized修飾一個函數。線程

二、同步函數要注意的事項 : 
1)若是是一個非靜態的同步函數的鎖對象是this對象,若是是靜態的同步函數的鎖對象是當前函數所屬的類的字節碼文件(class對象)。 
a)非靜態同步函數(鎖不住): 
使用形式一: 

使用形式二: 

b)靜態同步函數: 

圖解: 

2)同步函數的鎖對象是固定的,不能由你來指定的。code

三、同步代碼塊、同步函數對比(推薦使用: 同步代碼塊)。 
緣由: 
1)同步代碼塊的鎖對象能夠由咱們隨意指定,方便控制。同步函數的鎖對象是固定的,不能由咱們來指定。 
2)同步代碼塊能夠很方便控制須要被同步代碼的範圍,同步函數必須是整個函數的全部代碼都被同步了。對象

相關文章
相關標籤/搜索