今天要來記錄一下執行緒(Thread) !! 

先從 它的幾個重要屬性說起  

start(): 也就是開始跑執行緒中的 run()

sleep() : 顧名思義,就是讓執行緒睡眠 ,可設定睡多久就只要  thread.sleep(1000)  就是睡一秒

yield() : 先暫停休息一下(很快!!)

 join() : 使用這 則代表先跑完此呼叫之執行緒才跑其他執行緒

wait()及notify() : 這是一組配搭,如果呼叫 wait() 則會讓執行緒完全暫停 , 直到呼叫notify() 才讓此wait執行緒繼續

先簡單做一個範例:

class person extends Thread{

private String name;

public person(String n){

  this.name = n;} 

 public void run(){

try{
Thread.sleep((int)(1000*Math.random()));
}
catch(InterruptedException e){}  //  呼叫sleep 會產生InterruptedException 例外 ,所以要寫try catch;

System.out.println("我是"+name);

}}

執行端:

person  a = new person("A");

person  b = new person("B");

person  c = new person("C");

上面這個例子是用繼承Thread 方法來完成,但有時候類別只能繼承一項,可能會有所衝突,此時我們也可改為 實做"Runnable"介面來達到同樣的效果

但執行端就要稍微改一下為:

person a = new person("A");
person b = new person("B");
person c = new person("C");
Thread aa = new Thread(a,"AA");
Thread bb = new Thread(b,"BB");
Thread cc = new Thread(c,"CC");
aa.start();
bb.start();
cc.start();

 

再來就是 synchronized 方法 也就是同步多工

它的功能很簡單,也就是 在方法上冠上這個關鍵字,那麼值行緒在跑的時候便會有規矩的排隊進入這此方法內,也就是像排隊上廁所一樣

當A占據了一間廁所,B只能等A結束後才進入

下面有個小範例:

class Cbank{
static int sum = 0;
//synchronized
public synchronized static void add(int n){
int addM = sum;
addM += n;

try{
Thread.sleep((int)(1000*Math.random()));
}
catch(InterruptedException e){ }
sum = addM;
System.out.println("已領出:"+sum+"錢");

if (sum == 300)
{
Thread.yield();
}
}
}
class CCback extends Thread{
public void run(){
for(int i = 0 ; i<=3; i++)
Cbank.add(100);
}
}
public class testSynchronized {
public static void main(String[] args) {
// TODO Auto-generated method stub
CCback A = new CCback();
CCback B = new CCback();
CCback C = new CCback();
A.start();
B.start();
C.start();
}
}

在 add 方法冠上 synchronized

那麼就可以有效的計錄實際上這方法被呼叫幾次而套用再領錢的觀念上

 

最後再附上一個 wait() 及 notify 例子

class Callstock {
static int intStock = 0;

synchronized public void toExecution(int i ,int a){

while(intStock < a)
{
try
{
System.out.println("庫存僅剩"+intStock+",庫存不足,補貨中");
wait();}
catch(InterruptedException e){
}
}
intStock -= a;
notify();
System.out.println("第"+i+"拿取庫存"+i+"個,目前庫存剩餘"+intStock+"個");
}
synchronized public void toAddStock(int i,int b){
while (intStock > 20){
try{
System.out.println("目前庫存數已達"+intStock+",已過量,暫不新增庫存");
wait();
}
catch(InterruptedException e){}
}
intStock += b;
notify();
System.out.println("第"+i+"增加庫存量,目前庫存量為"+intStock);

}
}

class toExecution extends Thread{
Callstock callstock ;
public toExecution(Callstock b){
this.callstock = b;
}
public void run(){
//Callstock stock = new Callstock();
// 必須使用同一個執行緒才可notify正確
for(int i=0 ; i<= 10 ; i++)
{
callstock.toExecution(i, 3);
}
}
}
class toAddStock extends Thread{
Callstock callstock ;
public toAddStock(Callstock c){
this.callstock = c;
}
public void run(){
//Callstock stock = new Callstock();
for(int i=0 ; i<= 10 ; i++)
{
callstock.toAddStock(i, 4);
}
}
}
public class threadstock {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Callstock callstock = new Callstock();
toExecution A = new toExecution(callstock);
toAddStock B = new toAddStock(callstock);
A.start();
B.start();
int i = 6;
while(i >1)
{
System.out.println(i);
i--;
}
}
}

 

順道一題 : wait() 及 notify 皆須寫在synchronized 內

 

以上參考 旗標 java2 教學手冊  及 基峯"SCJP6.0認證手冊"

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 JoshS 的頭像
    JoshS

    JoshS的部落格

    JoshS 發表在 痞客邦 留言(0) 人氣()