一、進程和線程的基礎知識
1、進程和線程的概念
進程:運行中的應用程序稱為進程,擁有系統資源(cpu、內存)
線程:進程中的一段代碼,一個進程中可以有多段代碼。本身不擁有資源(共享所在進程的資源)
在java中,程序入口被自動創建為主線程,在主線程中可以創建多個子線程。
區別:
1、是否占有資源問題
2、創建或撤銷一個進程所需要的開銷比創建或撤銷一個線程所需要的開銷大。
3、進程為重量級組件,線程為輕量級組件
多進程: 在操作系統中能同時運行多個任務(程序)
多線程: 在同一應用程序中有多個功能流同時執行
2、線程的主要特點
①、不能以一個文件名的方式獨立存在在磁盤中;
②、不能單獨執行,只有在進程啟動后才可啟動;
③、線程可以共享進程相同的內存(代碼與數據)。
3、線程的主要用途
①、利用它可以完成重復性的工作(如實現動畫、聲音等的播放)。
②、從事一次性較費時的初始化工作(如網絡連接、聲音數據文件的加載)。
③、並發執行的運行效果(一個進程多個線程)以實現更復雜的功能
4、多線程(多個線程同時運行)程序的主要優點
①、可以減輕系統性能方面的瓶頸,因為可以並行操作;
②、提高CPU的處理器的效率,在多線程中,通過優先級管理,可以使重要的程序優先操作,提高了任務管理的靈活性;另一方面,在多CPU系統中,可以把不同的線程在不同的CPU中執行,真正做到同時處理多任務。
二、線程的創建和啟動
其實看看API,從Thread的構造方法,就可以看出創建一個線程的方式:
Thread() 分配新的 Thread 對象。 |
Thread(Runnable target) 分配新的 Thread 對象。 |
Thread(Runnable target,String name) 分配新的 Thread 對象。 |
Thread(String name) 分配新的 Thread 對象。 |
Thread(ThreadGroup group,Runnable target) 分配新的 Thread 對象。 |
Thread(ThreadGroup group,Runnable target,String name) 分配新的 Thread 對象,以便將 target 作為其運行對象,將指定的 name 作為其名稱,並作為 group 所引用的線程組的一員。 |
Thread(ThreadGroup group,Runnable target,String name, long stackSize) 分配新的 Thread 對象,以便將 target 作為其運行對象,將指定的 name 作為其名稱,作為 group 所引用的線程組的一員,並具有指定的堆棧大小。 |
Thread(ThreadGroup group,String name) 分配新的 Thread 對象。 |
后面4個構造方法創建一個線程並加入到一個線程組中,但是創建線程的方式和前面的相似。
java中創建一個線程有兩種方式:
1、繼承Thread類,重寫run()方法,然后直接new這個對象的實例,創建一個線程的實例。然后調用start()方法啟動線程
2、實現Runnable接口,重寫run()方法,然后調用new Thread(runnable)的方式創建一個線程,然后調用start()方法啟動線程
其實看Thread的源文件,發現它也是實現了Runnable接口的。
- public class Thread implements Runnable
1、繼承Thread類的方式
- public class Test1 {
- public static void main(String[] args) {
- System.out.println(Thread.currentThread().getName());
- MyThread myThread=new MyThread();
- myThread.start();
- }
- }
- class MyThread extends Thread{
- int i=0;
- @Override
- public void run() {
- while (i<10) {
- System.out.println(this.getName()+" i的值 "+i);
- i++;
- }
- }
- }
2、實現Runnable接口
- public class Test1 {
- public static void main(String[] args) {
- System.out.println(Thread.currentThread().getName());
- Thread thread=new Thread(new MyRunnable());
- thread.start();
- }
- }
- class MyRunnable implements Runnable{
- int i=0;
- @Override
- public void run() {
- while (i<10) {
- System.out.println(Thread.currentThread().getName()+" i的值 "+i);
- i++;
- }
- }
- }
注意:
①、在繼承Thread的方式中,可以使用getName()方法,來獲得當前線程的名字,這是因為在Thread類中,有這個方法。可是在實現Runnable方式中,卻不可以使用this.getName(),因為Runnable接口沒有這個方法(可以看出來,因為我們沒有提示我們需要重寫這個方法),所以只能通過Thread的靜態方法Thread.currentThread()取得當前的Thread對象,在調用getName()方法,來取得當前線程的名字。
②、對Java來說,run()方法沒有任何特別之處。像main()方法一樣,它只是新線程知道調用的方法名稱(和簽名)。因此,在Runnable上或者Thread上調用run方法是合法的。但並不啟動新的線程。只有調用start()方法才會啟動新線程。
3、兩種方式的對比
采用實現Runnable接口方式的多線程具有優勢,一般都會使用這種方式:
1、線程類只是實現了Runnable接口,還可以繼承其他類。
2、在這種方式下,可以多個線程共享一個Runnable target對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數據分開,形成清晰的模型,較好的體現了面向對象的思想。
source:http://blog.csdn.net/lonelyroamer/article/details/7948329
這一系列的文章很好!
Java多線程(一)、多線程的基本概念和使用
http://blog.csdn.net/lonelyroamer/article/details/7948329
Java多線程(二)、線程的生命周期和狀態控制
http://blog.csdn.net/lonelyroamer/article/details/7949969
Java多線程(三)、線程同步
http://blog.csdn.net/lonelyroamer/article/details/7956097
Java多線程(四)、線程池
http://blog.csdn.net/lonelyroamer/article/details/7993637
Java多線程(五)、多線程其他知識簡要介紹