1-1 進程
程序是靜止的,運行中的程序就是進程。
- 進程的三個特征:
- 動態性 : 進程是運行中的程序,要動態的占用內存,CPU和網絡等資源。
- 獨立性 : 進程與進程之間是相關獨立的,彼此有自己的獨立內存區域。
- 并發性 : 假如CPU是單核,同一個時刻其實內存中只有一個進程在被執行。 CPU會分時輪詢切換依次為每個進程服務,因為切換的速度非快,給我們的感覺這些進程在==同時執行,這就是并發性。==
- 并行:同一個時刻同時在執行。
1-2 線程
- 線程是屬于進程的。==一個進程可以包含多個線程,這就是多線程==。線程創建開銷相對于進程來說比較小。 線程也支持并發性。
- 線程的作用: 可以提高程序的效率,可以有更多機會得到CPU。
1-3 進程和線程的總結
進程是運行中的程序。有動態性,獨立性,并發性。一個進程可以包含多個線程,線程也支持并發。
多線程可以提高程序的整體效率,可以解決很多業務需求。因為多個線程是并發搶占CPU執行,所以多線程的執行會出現隨機性。
2-創建線程的三種方式
方式1:定義一個線程類繼承Thread類,然后重寫run()方法,再創建線程對象,調用start()方法啟動線程
/**
方式一的步驟:a.定義一個線程類繼承Thread類b.重寫Thread類的run()方法c.創建一個子線程對象d.調用線程對象的start()方法啟動線程(其實最終就是執行線程對象的run()方法)線程的注意:1.啟動線程不能直接調用run()方法,否則是普通對象的普通方法調用了,將失去線程特征。線程的啟動必須調用start()2.一般是先創建子線程,再申明主線程的任務,否則主線程任務總是先執行完!優缺點:優點:編碼簡單。缺點:線程類已經繼承了Thread類,不能再繼承其他類,功能被削弱了。不能做線程池。無法直接返回線程執行的結果。*/
public class ThreadDemo {// 自帶一個線程:main方法本身就是一個線程,是最牛逼的線程!public static void main(String[] args) {// c.創建一個子線程對象MyThread t = new MyThread();// d.啟動線程// 注意:啟動線程不能直接調用run()方法,否則是普通對象的普通方法調用了,將失去線程特征。// 線程的啟動必須調用start()t.start();for(int i = 0 ; i < 10; i++){System.out.println("main線程執行:"+i);}}
}// 線程類不是線程對象,是用來創建線程對象的。
// a.定義一個線程類繼承Thread類
class MyThread extends Thread{// b.重寫Thread類的run()方法@Overridepublic void run() {for(int i = 0 ; i < 10; i++){System.out.println("子線程執行:"+i);}}
}
方式2:定義一個線程任務類實現Runnable接口,然后重寫run()方法。創建線程任務對象,把線程任務對象包裝成線程對象,調用start()方法啟動線程
/**
a.定義一個線程任務類實現Runnable接口。重寫run()方法
b.創建一個線程任務對象
c.把線程任務對象包裝成一個線程對象-- public Thread(Runnable target)
d.調用線程對象的start()方法啟動線程。優缺點:缺點:編程相對復雜,不能直接返回線程的執行結果優點:1. 一個任務對象可以被反復包裝成多個線程對象。2. 可以避免java中的單繼承的局限性。因為線程任務對象只是實現了接口,還可以繼續繼承其他類和實現其他接口。3. 實現解耦操作,線程任務對象代碼可以被多個線程共享,代碼和線程獨立。4. 線程池只能放入實現Runable或Callable類線程,不能直接放入繼承Thread的類。適合做線程池。*/
public class ThreadDemo {public static void main(String[] args) {// b.創建一個線程任務對象Runnable target = new MyRunnable();// c.把線程任務對象包裝成線程對象Thread t = new Thread(target);// d.調用線程對象的start()方法啟動線程。t.start();Thread t1 = new Thread(target);t1.start();for(int i = 0 ; i < 10; i++){System.out.println(Thread.currentThread().getName()+"=>"+i);}}}
// 線程任務類
// a.定義一個線程任務類實現Runnable接口。
class MyRunnable implements Runnable{@Overridepublic void run() {for(int i = 0 ; i < 10; i++){System.out.println(Thread.currentThread().getName()+"=>"+i);}}
}
方式三:定義一個線程任務類實現Callable接口
/**
a.定義一個線程任務類實現Callable接口。
b.重寫call()方法。
c.把線程任務對象包裝成一個未來任務對象。
d.把未來任務對象包裝成一個線程對象。
e.調用線程對象的start()方法啟動線程。
優缺點:缺點:編碼復雜。優點:全是優點。可以繼續繼承其他類。可以做線程池。可以得到線程返回的結果。可以做資源共享操作*/
public class ThreadDemo {public static void main(String[] args) {MyCallable call = new MyCallable();// c.把線程任務對象包裝成一個未來任務對象。/*** 未來任務對象: FutureTask* 1.可以通過未來任務對象去獲取線程執行的結果。* 2.未來任務對象其實就是一個Runnable的對象。*/FutureTask<String> target = new FutureTask<>(call);// d.把未來任務對象包裝成一個線程對象。Thread t = new Thread(target);// e.調用線程對象的start()方法啟動線程。t.start();for(int i = 0 ; i < 10; i++){System.out.println(Thread.currentThread().getName()+"=>"+i);}try {// 線程的執行的結果!String result = target.get();System.out.println(result);} catch (Exception e) {e.printStackTrace();}}
}
// a.定義一個線程任務類實現Callable接口。申明返回值類型
class MyCallable implements Callable<String>{// b.重寫call()方法。@Overridepublic String call() throws Exception {int count = 0 ;for(int i = 0 ; i < 10; i++){count+=(i+1) ; // 1-10的和。System.out.println(Thread.currentThread().getName()+"=>"+i);}return Thread.currentThread().getName()+"求和結果:"+count;}
}