java在語言層級實現的多線程操作的一些原語,用起來比較方便,不像C、C++之類的要叫用作業系統功能才能實現多線程。這裡展示一個範例show一下java多線程就是這樣簡單,一點也不神秘,java讓在課本上經常講的多任務多執行緒很方便的走到初學者的代碼中來。(但是也很方便創造deadlock,死結很難發現,如果不瞭解就最好不要用,不是必要場合不要用)。至於書上雲的一些線程狀態以及各狀態間的轉換則都是一樣的,java多了一個線程組,便於以group的方式管理大量線程,更多介紹還是去看API或者google,baidu吧,記錄之供參考。如果你能夠自己寫一遍生產者消費者(也有稱讀者寫者)就有了3、5成功力了吧,那樣才能夠考慮把它用到你的production代碼中去。
主要的就是一個Thread類,Thread類擁有一個Run()方法,還有一個Thread.start()來啟動線程開工。實現多線程有兩個方法:
1.將要並存執行的操作封裝到一個繼承自Thread的類中去
代碼
public class thread_ex extends Thread...{
public void init() ...{
}
public void start() ...{
//**will cll run() defualt.
}
public void stop() ...{
}
public void run()...{
//**do some parallelization works.
}
}
2.延伸Runnable介面,滿足一些繼承了其他類又想多線程的(因為java不像C++一樣支援多繼承)
public class ThreadTest extends FatherClass implements Runnable
public void init() ......{
}
public void start() ......{
//**will cll run() defualt.
}
public void stop() ......{
}
public void run()......{
//**do some parallelization works.
}
}
與線程有關的幾個關鍵詞是很重要的:synchronize wait notify notifyAll
如果不能很好的理解他們還是不要用的好。簡單的介紹如下
synchronize 修飾定義一個對象或者方法或者屬性的訪問必須序列化訪問,顧名思義像在銀行取錢要排隊一樣,那個業務員就是一個synchronize 對象。只有像我等無錢之輩才去排隊,那些個VIP自然不用了。
wait 和notify notifyAll是一家的,他們是對象級的鎖,餘天生駑鈍,這個偶翻了許多資料才理解,如果不能理解就看代碼吧。多線程中的一個去訪問共用資源發現有人使用,於是就在這個資源上面wait,佔用者如果使用完了就notify()一下通知下一個等待者可以進來了,notifyAll()就是說在外面等的一起上吧!可是只能服務與一個人,於是大家搶著進去,力氣大的自然佔便宜。可是在java世界裡面JVM說了算。
有wait和notify的地方一定有synchronize,反過來不成立,wait 和notify不在Thread的勢力範圍
-----------------------------------------------------------
說正題,直奔代碼!本例設計到三個類:ThreadController,PrintThread,Resource;也是顧名思義就不做解釋。放代碼:
代碼
public class Resource...{
public static boolean inUse;
//public boolean inUse=false;
String name;
int sleepTime=0;
public synchronized void out(String n)...{
this.name=n;
while(Resource.inUse==true)
try...{
System.out.println("Name:"+getName()+" Waiting...");
this.wait();
}catch(InterruptedException ie)...{
ie.printStackTrace();
}
Resource.inUse=true; // entry the block and lock it
try...{
sleepTime=(int)(Math.random()*5000);
System.out.println("Name:"+getName()+" in use; define Sleep Time: "+sleepTime+",wait 50000 to exit the synchronize block");
Thread.sleep(5000);
System.out.println("Name:"+getName()+" end 5000 sleep . Sleep some time after notify to test if others can end first");
Thread.sleep(5000-sleepTime);
System.out.println("Name:"+getName()+" will Exit the synchronize block");
Resource.inUse=false;
System.out.println("Name:"+getName()+" End. "+Resource.inUse);
this.notifyAll();
}catch(InterruptedException ie)...{
ie.printStackTrace();
}
}
public String getName()...{
return name;
}
}
代碼
public class ThreadController...{
public static void main(String args[])...{
PrintThread t1,t2,t3,t4;
Resource r=new Resource();
Resource.inUse=false;
t1 = new PrintThread("1",r);
t2 = new PrintThread("2",r);
t3 = new PrintThread("3",r);
t4 = new PrintThread("4",r);
t1.start();
t2.start();
t3.start();
t4.start();
System.out.println("Controller ended...");
//System.exit(0);
}
}
代碼
public class PrintThread extends Thread...{
int sleepTime;
Resource rs;
public PrintThread(String id,Resource r)...{
super(id);
this.rs=r;
}
public void run()...{
try...{
System.out.println("Thread :"+getName()+" start...... wait to entry synchronize block");
rs.out(getName());
sleepTime=(int)(Math.random()*5000);
System.out.println("Thread :"+getName()+" start to sleep"+sleepTime+"mms");
sleep(sleepTime);
}catch(InterruptedException ie)...{
ie.printStackTrace();
}
System.out.println("Thread :"+getName()+" wakeup, end.");
}
}