線程安全問題的解決方案


/*
進程: 進程就是正在運行的應用程序。 進程了負責了內存空間划分。

線程: 一個進程中的 代碼是由線程去執行的,線程也就是進程中一個執行路徑。

多線程: 一個進程中有多個線程可以同時執行任務。


多線程 的好處:
    1. 解決一個進程中可以同時執行多個任務的問題。
    2. 提高了資源利用率。

多線程的弊端:
    1. 增加了cpu的負擔。
    2. 降低了一個進程中線程 的執行概率。
    3. 出現了線程 安全問題。
    4. 會引發死鎖現象。
    

自定義線程 的實現方式:
    
    方式一 : 
        1. 自定義一個類繼承Thread類。
        2. 重寫Thread類的run方法,把自定義線程的任務代碼寫在run方法上。
        3. 創建Thread的子類對象,並且調用start方法啟動一個線程。 
        
    注意:千萬不要直接調用run方法,調用start方法的時候線程就會開啟,線程一旦開啟就會執行run方法中代碼,如果直接調用
    run方法,那么就 相當於調用了一個普通的方法而已。
    
    
線程安全問題:

線程安全出現 的根本原因:
    1. 存在兩個或者兩個以上 的線程對象共享同一個資源。
    2. 多線程操作共享資源的代碼 有多句。
    


線程安全問題的解決方案:
    
    方式一: 可以使用同步代碼塊去解決。
    
    格式:
        synchronized(鎖對象){
            需要被同步的代碼
        }
    
同步代碼塊要注意的事項:
    1. 鎖對象可以是任意的一個對象。
    2. 一個線程在同步代碼塊中sleep了,並不會釋放鎖對象。
    3. 如果不存在着線程安全問題,千萬不要使用同步代碼塊,因為會降低效率。
    4. 鎖對象必須是多線程共享的一個資源,否則鎖不住。
    
    
    方式二:同步函數  :  同步函數就是使用synchronized修飾一個函數。
    
    同步函數要注意的事項 :
        1. 如果是一個非靜態的同步函數的鎖 對象是this對象,如果是靜態的同步函數的鎖 對象是當前函數所屬的類的字節碼文件(class對象)。
        2. 同步函數的鎖對象是固定的,不能由你來指定 的。

    
    推薦使用: 同步代碼塊。
        原因:
            1. 同步代碼塊的鎖對象可以由我們隨意指定,方便控制。同步函數的鎖對象是固定 的,不能由我們來指定。
            2. 同步代碼塊可以很方便控制需要被同步代碼的范圍,同步函數必須是整個函數 的所有代碼都被同步了。
            


需求: 一個銀行賬戶5000塊,兩夫妻一個拿着 存折,一個拿着卡,開始取錢比賽,每次只能取一千塊,要求不准出現線程安全問題。
        
*/

class BankThread extends Thread{
    
    static    int count = 5000;
    
    public BankThread(String name){
        super(name);
    }
    
    @Override  //
    public synchronized  void run() {
        while(true){
            synchronized ("鎖") {                
                if(count>0){
                    System.out.println(Thread.currentThread().getName()+"取走了1000塊,還剩余"+(count-1000)+"元");
                    count= count - 1000;
                }else{
                    System.out.println("取光了...");
                    break;
                }
            }
        }
    }    
    
    
    //靜態的函數---->函數所屬 的類的字節碼文件對象--->BankThread.class  唯一的。
    public static synchronized  void getMoney(){
        
    }
    
}


public class Demo1 {

    public static void main(String[] args) {
        //創建兩個線程對象
        BankThread thread1 = new BankThread("老公");
        BankThread thread2 = new BankThread("老婆");
        //調用start方法開啟線程取錢
        thread1.start();
        thread2.start();
        
        
    }
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM