恬然自得.活在當下: [功課] 撰寫三個執行緒的程式,觀察其執行順序的結果

2011年3月22日 星期二

[功課] 撰寫三個執行緒的程式,觀察其執行順序的結果

這次比較特別,因為老師出的功課中,有一個計算若是用整數資料形態,會發生溢位的問題,事後詢問老師,對此有三種解決方式,以下會為大家說明一下。

貼上執行結果:
T1:1
T1:3
T2:100
T2:99
T2:98
T2:97
T2:96
T1:6
T1:10
T1:15
T1:21
...省略
T3:2.0
T3:8.0
...省略
T3:48.0
T3:384.0
...省略
T2:0
T1:903
T1:5050
T3:3.4942066022971404E75
T3:3.4243224702511974E77
T3:3.4243224702511973E79



大家可以注意第三個執行緒的程式碼,老師提供三種解決方式:
1.int改成用double宣告。
2.將溢位視為Exception,當溢位時顯示訊息。
3.改成用BigInteger類別來包覆變數,利用類別方法multiply來計算乘積。

寫法僅供參考,畢竟Java才學了半年左右吧 >”<
(大家記得註解和程式碼要自己重新打過唷,工讀生會檢查)

底下依序貼上方法一、二、三:
public class s11967046 {
/*請以今天3/16課堂中所學範例,試撰寫一java程式,
 * 建立三個執行緒,並同時執行之。
 *  1.第一個執行緒執行1-100的加總動作。
 *  2.第二個執行緒執行100至1的遞減動作。
 *  3.第三個執行緒執行計算1-100中偶數相乘。
 * 須輸出每一執行步驟,例如1-100加總: 1 3 6 10 ... 
 * 注意:以學號為主程式命名。
 * */

 public static void main(String[] args) {
  //宣告三個執行緒,並且給它們取名
  thread1 t1 = new thread1("T1");
  thread2 t2 = new thread2("T2");
  thread3 t3 = new thread3("T3");
  
  //啟動三個執行緒
  t1.start();
  t2.start();
  t3.start();
 }
}

//執行1-100的加總動作。
class thread1 extends Thread{
 int sum; //宣告儲存結果的變數
 
 //建構子呼叫父類別的建構子,功能是替執行緒取名
 public thread1(String name){
  super (name);
 }
 
 //覆寫run方法
 public void run(){
  for (int i =1 ; i<=100;i++){
   sum+=i; //相加後的結果儲存於sum中
   //顯示執行緒的名字和sum結果
   System.out.println(Thread.currentThread().getName() 
     + ":" + sum);
  }
 }
}

//執行100至1的遞減動作。
class thread2 extends Thread{
 
 //建構子呼叫父類別的建構子,功能是替執行緒取名
 public thread2(String name){
  super (name);
 }
 
 //覆寫run方法
 public void run(){
  for (int i = 100 ; i >= 0;i--){
   //顯示執行緒的名字和i
   System.out.println(Thread.currentThread().getName() 
     + ":" + i);
  }
 }
}

//執行計算1-100中偶數相乘。
class thread3 extends Thread{
 double sum = 1; //宣告儲存結果的變數
 
 //建構子呼叫父類別的建構子,功能是替執行緒取名
 public thread3(String name){
  super (name);
 }
 
 //覆寫run方法
 public void run(){
  for (int i =1 ; i<=100;i++){
   //將1-100中是偶數的數字篩選出來
   if (i%2 == 0){
    //計算乘積
    sum*=i;
    //顯示執行緒的名字和big結果
    System.out.println(Thread.currentThread().getName() 
     + ":" + sum );
   }
      
  }
 }
}


方法二:
//執行計算1-100中偶數相乘。
class thread3 extends Thread{
 int sum = 1; //宣告儲存結果的變數
 
 //建構子呼叫父類別的建構子,功能是替執行緒取名
 public thread3(String name){
  super (name);
 }
 
 //覆寫run方法
 public void run(){
  try{
   for (int i =1 ; i<=100;i++){
    //將1-100中是偶數的數字篩選出來
    if (i%2 == 0){
     //計算乘積
     sum*=i;
     //顯示執行緒的名字和sun結果
     System.out.println(Thread.currentThread().getName() 
      + ":" + sum ); 
    }
    
    //當sum出現負數,表示溢位了
    if(sum < 0){
     //利用throw丟出ArithmeticException
     throw new ArithmeticException();
    }
   }
   
  }catch(ArithmeticException e){
   System.out.println("真抱歉,sum已經溢位了");
  } 
 }
}
方法三:

import java.math.BigInteger; //記得import這個類別

//執行計算1-100中偶數相乘。
class thread3 extends Thread{
 int sum = 1; //宣告儲存結果的變數
 //將sum放入新建立的BigInteger物件中,以方便儲存大量的數字
 BigInteger big = new BigInteger(Integer.toString(sum));
 BigInteger big2 = null; //宣告big2先指向空的指標
 
 //建構子呼叫父類別的建構子,功能是替執行緒取名
 public thread3(String name){
  super (name);
 }
 
 //覆寫run方法
 public void run(){
  for (int i =1 ; i<=100;i++){
   //將1-100中是偶數的數字篩選出來
   if (i%2 == 0){
    //將偶數放入big2物件中,用於和big相乘
    big2= new BigInteger(Integer.toString(i));
    //相乘後的乘積儲存與big
    big = big.multiply(big2);
    //顯示執行緒的名字和big結果
    System.out.println(Thread.currentThread().getName() 
     + ":" + big );
   }
   
  }
 }
}

沒有留言:

張貼留言

歡迎提供良性建議^_^