進程與線程
理解進程與線程:
1.DOS有一個明顯的特點,就是一旦病毒入侵,系統就會死機,因為傳統的DOS系統是單進程處理方式,所以只有一個程序運行,其它程序無法運行。
而windows系統中,即使出現病毒,系統照樣可以使用,因為windows系統是采用多進程處理方式,在同一個時間段上會有多個程序在運行。
2.對於word來說每次啟動一個word實際上都是在操作系統上分配一個進程。而線程實際上是在進程的基礎上進一步划分,從word來看可以把拼寫檢查當做一個線程進行處理。當然會同時存在多個線程。
3.如果一個進程沒有了,線程一定會消失;但線程消失了,進程未必會消失。而且線程都是在進程的基礎上並發同時運行。
4.下面來看進程與線程的概念:
進程是程序的動態執行過程,它經歷了從代碼加載,執行,到執行完畢的一個完整過程。這個過程也是進程本身從產生、發展,到最終消亡的一個過程。
多線程是實現並發機制的一個有效手段。進程和線程一樣都是實現並發的基本單位。
理解多線程:如果現在同時有多個任務,則所有的系統的資源是共享的,被所有線程所公用,但是程序處理需要CPU,傳統單核CPU來說同一個時間段會有多個程序執行,但是在同一個時間點上只能存在一個程序運行,也就是說所有的程序都要搶占CPU資源。但是當CPU已經發展到多核的狀態了,在一個電腦上可能會存在多個CPU,這個時候就可以非常清楚的發現多線程操作間是如何進行並發的執行的。
5.java實現多線程:
兩種方式:(1)繼承Thread
(2)實現Runnable接口
先調用start方法,在執行run方法。這是為什么呢?打開Thread的類定義,在jdk的src.zip中全部是java的源程序代碼,直到找到java.lang.Thread類的定義:
public synchronized void start(){
if(threadStatus != 0)
throw new IllegalThreadStateException();
start0();
if(stopBeforeStart){
stop0(throwableFromStop);
}
}
private native void start();
start()方法可能拋出異常。
stopBeforeStart是一個boolean型變量,native關鍵字表示由java調用本機操作系統函數的一個關鍵字。在java中,運行java程序調用本機的操作系統的函數已完成特定的功能。
證明:如果現在要想實現多線程的話,則肯定需要操作系統的支持,因為多線程操作系中牽涉到一個搶占CPU的情況,要等待CPU進行調度,這一點肯定需要操作系統的底層支持,所以使用了native調用本機的系統函數。而且在各個操作系統中實現底層代碼肯定是不同的,所以使用native關鍵字也可以讓JVM自動調整不同的JVM實現。
threadStatus也表示一種狀態,如果線程已經啟動了在調用start方法的時候就有可能產生異常。
繼承Thread實現多線程:
class myThread extends Thread{
private String name;
public myThread(String name){//通過構造方法配置name屬性
this.name = name;
}
public void run(){//重寫run方法
for(int i = 0;i<10; i++){
System.out.println(name +"運行,i="+i);
}
}
}
public class ThreadDemo{
public static void main(String []args){
myThread mt1 = new MyThread("線程A");//實例化對象
mt1.start();//調用線程主體
mt1.start();//異常
}
}
Runnable接口:在java中可以通過實現Runnable接口的方式實現多線程,Runnable接口中只定義了一個抽象的方法。public void run();
在Runnable中並沒有start()方法,那么怎樣才能使用start()方法呢?在Thread類中有構造方方法public Thread(Runnable target ){}利用此構造方法啟動多線程。
class MyThread implements Runnable{
private String name;
public MyThread(String name){
this.name = name;
}
public void run(){
for(int i = 0;i<10;i++){
System.out.Println(name+"運行,i = "+i);
}
}
}
public class myThreadDemo{
public static void main(String []args){
MyThread mt1 = new MyThread("線程A");//實例化對象
MyThread mt2= new MyThread("線程B");
Thread t1 = new Thread(mt1);//實例化Thread類對象
Thread t2 = new Thread(mt2);
t1.start();//啟動多線程和
t2.start();
}
}
Thread類與Runnable接口的聯系:
Thread 定義:
public class Thread extends Object implements Runnable 發現Thread類也是Runnable接口的子類,使用了代理的機制完成。
Thread類與Runnable接口的區別:
使用Thread類操作多線程的時候無法達到資源共享的目的,而使用Runnable接口實現的多線程操作可以實現資源共享。
Thead類與Runnable接口的使用結論:
實現Runnable接口比繼承Thread類有如下明顯的優點:
(1)適合多個相同程序的代碼的線程去處理同一個資源。
(2)可以避免由於單繼承局限所帶來的影響。
(3)增強了程序的健壯性,代碼能夠被多個線程共享,代碼與數據是獨立的。
線程的狀態:
創建狀態:准備好了一個多線程對象:Thread t = new Thread();
就緒狀態:調用了start()方法,等待CPU進行調度。
運行狀態:執行run方法
阻塞狀態:暫時停止執行,可能將資源交給其他線程使用。
終止狀態:(死亡狀態):線程執行完畢了,不再使用了。
