關于線程和進程的學習,我們已經進行了很多遍了,但是對于這兩者的區別還是不知道怎么去理解.所以做一下總結吧。
### 關于進程和線程的區別
**a.地址空間和其它資源**:進程間相互獨立,同一進程的各線程間共享。某進程內的線程在其它進程不可見。
**b.通信**:進程間通信IPC,線程間可以直接讀寫進程數據段(如全局變量)來進行通信——需要進程同步和互斥手段的輔助,以保證數據的一致性。
**c.調度和切換**:線程上下文切換比進程上下文切換要快得多。
**d.在多線程OS中,進程不是一個可執行的實體。**
一個簡單的例子,就是進程就好像一個工廠,這個工廠做產品需要一些資源.而線程就好像工廠中的工人,這些工人之間的資源時共享的.
### 線程的實現
線程的實現由兩種方法,一種是繼承分別為繼承Thread類和實現Runable接口。
下面是兩段代碼分別實現這兩個方法。
### 一.使用Runable接口
~~~
public class MyThread {
public static void main(String[] args)
{
Runner r = new Runner();
// r.run();//使用此處我們可以看到兩個方法分別執行
Thread t=new Thread(r);
t.start();//使用多線程,我們可以發現我們的兩個方法是同時執行的
for(int i = 0;i<100;i++)
{
System.out.println("Main Thread:"+i);
}
}
}
class Runner implements Runnable
{
public void run()
{
for(int i=0;i<100;i++)
{ System.out.println("runner:"+i);
}
}
}
~~~
### 二.繼承Thread類
~~~
public class MyThread {
public static void main(String[] args)
{
Runner r = new Runner();
r.start();
for(int i = 0;i<100;i++)
{
System.out.println("Main Thread:"+i);
}
}
}
class Runner extends Thread
{
public void run()
{
for(int i=0;i<100;i++)
{ System.out.println("runner:"+i);
}
}
}
~~~
? 使用多線程得到的輸出結果:
? ? ? ? ? ? ? ??
使用Runnable階段創建線程時,需要首先編寫一個實現Runnable接口的類.然后實例化該類的對象,這樣就建立了?
Runnable對象,接下來使用構造方法創建Thread實例.最后使用Start()方法啟動線程.
當一個類繼承了Thread后,就可以在該類中覆蓋run()方法,將實現線程功能的代碼寫入run()中.然后調用Thread的Start()方法.
看過之后我們會發現兩個方法是這么的相似.如果我們查API,我們就會明白實質上Thread類就是實現了Runnable接口,其中的Run方法就是對Runnable接口中Run()方法的具體實現。
### 生命周期
線程的生命周期,包括出生、就緒、運行、等待、休眠、阻塞和死亡七種狀態。
下面的一張圖展示了這幾個狀態的聯系。其中也展示了線程的一些操作

### 線程的同步
在多線程中會發生兩個線程搶占資源的的問題。為了解決這個問題,java提供了線程同步機制。
我們通過一個實例來理解一下這個機制。這張圖實現了一個簡單的買門票的過程.門票的張數不能是負值.
~~~
public class MyThread {
public static void main(String[] args)
{
ThreadSafeTest t = new ThreadSafeTest();
//實例化四個線程實例
Thread tA=new Thread(t);
Thread tB=new Thread(t);
Thread tC=new Thread(t);
Thread tD=new Thread(t);
//啟動這四個線程實例
tA.start();
tB.start();
tC.start();
tD.start();
}
}
class ThreadSafeTest implements Runnable
{
int num=10;
public void run()
{
while(true){
if(num>0){
try
{
Thread.sleep(100);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("門票還有" + num + "張" );
num=num-1;
}
}
}
}
~~~
執行結果為:

這個過程中我們可以看到出現了負值,這是由于同時創建了四個線程,這個四個線程同時執行run方法,而且這四個線程同是取得數值,同是遞減.導致剩余門票的張數出現上面的情況.
然后,我們給run方法加入同步機制.
~~~
public class MyThread {
public static void main(String[] args)
{
ThreadSafeTest t = new ThreadSafeTest();
//實例化四個線程實例
Thread tA=new Thread(t);
Thread tB=new Thread(t);
Thread tC=new Thread(t);
Thread tD=new Thread(t);
//啟動這四個線程實例
tA.start();
tB.start();
tC.start();
tD.start();
}
}
class ThreadSafeTest implements Runnable
{
int num=10;
public void run()
{
while(true)
{
synchronized("")//該關鍵字的使用就保證了同步
{
if(num>0){
try
{
Thread.sleep(100);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("門票還有" + num + "張" );
num=num-1;
}
}
}
}
}
~~~

### 總結
學習了多線程編程就像進入了一個全新的領域,它與以往的編程思想不同,現在很多的程序語言都以支持和擴展多線程,作為初學者應該及時轉變我們的編程思路,是我們的變成進入一個多線程編程的思維方式.同時多線程也是一種復雜的機制,完全理解它我們還要更深入的去研究