線程安全問題
??? 當多條語句在操作同一個線程共享數據時,一個線程對多條語句只執行了一部分,還沒有執行完,
?? ?另一個線程參與進來執行。導致共享數據的錯誤。
解決辦法:
?? ?對多條操作共享數據的語句,只能讓一個線程都執行完。在執行過程中,其他線程不可以參與執行。
Java對于多線程的安全問題提供了專業的解決方式。
就是同步代碼塊。
synchronized(對象)
{
?? ?需要被同步的代碼
}
對象如同鎖。持有鎖的線程可以在同步中執行。
沒有持有鎖的線程即使獲取cpu的執行權,也進不去,因為沒有獲取鎖。
同步的前提:
1,必須要有兩個或者兩個以上的線程。
2,必須是多個線程使用同一個鎖。
必須保證同步中只能有一個線程在運行。
好處:解決了多線程的安全問題。
弊端:多個線程需要判斷鎖,較為消耗資源,
?
多線程程序中如何找問題(那些代碼該同步、那些不該同步):
1.明確那些代碼是多線程運行代碼。
2.明確共享數據。
3.明確多線程運行代碼中那些語句是操作共享數據的。
同步函數(將關鍵字synchronized作為修飾符修飾函數,使其具有同步性)


//同步函數 class bank {int money;//將同步關鍵字synchronized方在方法中作為修飾符,使方法具有同步性public synchronized void add(int i){money = money+i;} }class people implements Runnable {private bank b = new bank();public void run(){for(int i=0;i<3;i++){b.add(100);System.out.println(Thread.currentThread().getName()+"存入了"+100+"元");System.out.println("金庫中的金額為:"+b.money);}} }class userMain {public static void main(String [] args){people p = new people();Thread t1 = new Thread(p);Thread t2 = new Thread(p);t1.start();t2.start();} }
?同步函數中使用的鎖是this
如果同步函數被靜態修飾后,使用的鎖是什么呢?
通過驗證,發現不在是this。因為靜態方法中也不可以定義this。
靜態進內存是,內存中沒有本類對象,但是一定有該類對應的字節碼文件對象。
類名.class? 該對象的類型是Class
靜態的同步方法,使用的鎖是該方法所在類的字節碼文件對象。 類名.class