/* 進程: 進程就是正在運行的應用程序。 進程了負責了內存空間划分。 線程: 一個進程中的 代碼是由線程去執行的,線程也就是進程中一個執行路徑。 多線程: 一個進程中有多個線程可以同時執行任務。 多線程 的好處: 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(); } }
