完數的Java多執行緒並行程式設計-平行計算
目錄
2.2 使用Runnable介面實現並行的演算法設計... 3
1.問題描述
一個數如果恰好等於它的因子之和,這個數就稱為“完數”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完數。輸入一個數n,程式設計找出n以內的所有完數及其個數。
2.演算法設計
2.1 序列演算法設計
序列演算法步驟如下:
①因為1不算入一個完數,所以令數i=2,初始化答案值ans=0;
②因為1是任何數的一個因數,所以可初始化因數之和sum=1;
③令數k=2;
④如果數i能整除數k,說明k是i的一個因數,則sum += k;
⑤若k<=i/2(控制範圍保證i%k能進行計算),++k,轉到④,否則轉到⑥;
⑥若sum = i,++ans;
⑦若i <=n,++i,轉到②,否則轉到⑧;
⑧函式返回答案值ans。
2.2 使用Runnable介面實現並行的演算法設計
並行演算法步驟如下:
①定義好run()方法,以實現了run()方法的work類為引數建立系統類Thread的物件,來繼承定義好的run()方法;
②兩個執行緒分別從2~n和3~n開始並行執行計算;
③執行完畢將兩個執行緒的結果求和;
④序列執行2~n的計算。
2.3繼承Thread類實現並行的演算法設計
並行演算法步驟如下:
①在Number類中定義一個Thread類,在主函式中建立兩個執行緒,使這兩個執行緒並行執行;
②兩個執行緒分別從2~n和3~n開始並行執行計算;
③執行完畢將兩個執行緒的結果求和;
④序列執行2~n的計算。
2.4 理論加速比分析
若p個處理器上資料量為n,則S=np/(n+2plogp)。
本機測試中,p=2:若n=10000,則S=1.99976;若n=100000,則S=1.99998。
3.使用Runnable介面的並行演算法實現
3.1 程式碼及註釋
/*問題描述:一個數如果恰好等於它的因子之和,這個數就稱為“完數”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完數。程式設計找出n以內的所有完數。
*/
//
importjava.util.Scanner;
public class Number
{
public static void main(String[] args) throws InterruptedException
{
System.out.print("請輸入n=");
Scanner input = newScanner(System.in);
long n = input.nextInt();//計算範圍是1~n
/********並行*******/
//1不是完數分成兩個執行緒,分別從2和3開始
work work1 = newwork(2, n);
work work2 = newwork(3, n);
Thread thread1 = newThread(work1);
Thread thread2 = newThread(work2);
long startTime = System.currentTimeMillis();
thread1.start();//啟動執行緒
thread2.start();
thread1.join();
thread2.join();
long endTime = System.currentTimeMillis();
System.out.println("並行結果=" +(work1.getSum() + work2.getSum()));//兩個執行緒的結果求和
System.out.println("並行時間=" +(endTime - startTime));
/********序列*******/
startTime = System.currentTimeMillis();
work work = newwork(2, n);
long sum = work.sum();
endTime = System.currentTimeMillis();
System.out.println("序列結果=" +sum);
System.out.println("序列時間=" +(endTime - startTime));
}
}
class work implements Runnable
{
private longstart;
private longend;
private long sum= 0;
public work(long start, long end)
{
super();
this.start = start;
this.end = end;
}
public void run()
{
for (long i = start; i <= end; i += 2) //1不算入一個完數。
{
longtemp = 1; //數的因數之和,1是任何數的一個因數。
for (long k =2; k <= i / 2; k++) //k<=i/2是要保證i%k能進行計算。
if(i%k == 0)
temp += k; //因數之和
if(temp == i) //找到一個完數
++sum; //函式返回答案值
}
}
public long sum()
{
for (long i = start; i <= end; i++) //1不算入一個完數。
{
longtemp = 1; //數的因數之和,1是任何數的一個因數。
for (long k =2; k <= i / 2; k++) //k<=i/2是要保證i%k能進行計算。
if(i%k == 0)
temp += k; //因數之和
if(temp == i) //找到一個完數
++sum; //函式返回答案值
}
return sum;
}
public long getSum()
{
returnsum;
}
}
3.2 執行結果截圖
(1)小資料量驗證正確性的執行結果截圖(不考慮加速比)
(2)大資料量獲得較好加速比的執行結果截圖
(體現序列時間、並行時間和好的加速比)
3.3 實驗加速比分析
若n=10000,S=Ts/Tp=1.9083;若n=100000,S=Ts/Tp=1.9636。
實驗加速比與理論加速比相差不大,在誤差允許範圍內可認為結果正確。
4.繼承Thread類的並行演算法實現
4.1 程式碼及註釋
/*問題描述:一個數如果恰好等於它的因子之和,這個數就稱為“完數”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完數。程式設計找出n以內的所有完數。
*/
//
importjava.util.Scanner;
public class Number extends Thread
{
private longstart;
private longend;
private long sum= 0;
public Number(long start, long end)
{
super();
this.start = start;
this.end = end;
}
public void run()
{
for (long i = start; i <= end; i += 2) //1不算入一個完數。
{
longtemp = 1; //數的因數之和,1是任何數的一個因數。
for (long k =2; k <= i / 2; k++) //k<=i/2是要保證i%k能進行計算。
if(i%k == 0)
temp+= k; //因數之和
if(temp == i) //找到一個完數
++sum; //函式返回答案值
}
}
public long sum()
{
for (long i = start; i <= end; i++) //1不算入一個完數。
{
longtemp = 1; //數的因數之和,1是任何數的一個因數。
for (long k =2; k <= i / 2; k++) //k<=i/2是要保證i%k能進行計算。
if(i%k == 0)
temp += k; //因數之和
if(temp == i) //找到一個完數
++sum; //函式返回答案值
}
return sum;
}
public long getSum()
{
return sum;
}
public static void main(String[] args) throws InterruptedException
{
System.out.print("請輸入n=");
Scanner input = newScanner(System.in);
long n = input.nextInt();//計算範圍是1~n
/**********並行**********/
Number thread1 = newNumber(2, n);//1不計入完數
Number thread2 = newNumber(3, n);
long startTime = System.currentTimeMillis();
thread1.start();
thread2.start();
thread1.join();
thread2.join();
long endTime = System.currentTimeMillis();
System.out.println("並行結果=" +(thread1.getSum() + thread2.getSum()));
System.out.println("並行時間=" +(endTime - startTime));
/**********序列**********/
startTime = System.currentTimeMillis();
Number serial = newNumber(2, n);
long sum = serial.sum();
endTime = System.currentTimeMillis();
System.out.println("序列結果=" +sum);
System.out.println("序列時間=" +(endTime - startTime));
}
}
4.2 執行結果截圖
(1)小資料量驗證正確性的執行結果截圖(不考慮加速比)
(2)大資料量獲得較好加速比的執行結果截圖
(體現序列時間、並行時間和好的加速比)
4.3 實驗加速比分析
若n=10000,S=Ts/Tp=2.0436;若n=100000,S=Ts/Tp=1.8717。
實驗加速比與理論加速比相差不大,在誤差允許範圍內可認為結果正確。
相關文章
- 使用Java實現多執行緒程式設計Java執行緒程式設計
- Java-基礎程式設計-多執行緒Java程式設計執行緒
- Java多執行緒程式設計—鎖優化Java執行緒程式設計優化
- python 多執行緒程式設計Python執行緒程式設計
- JavaScript多執行緒程式設計JavaScript執行緒程式設計
- Python多執行緒程式設計Python執行緒程式設計
- 多執行緒程式設計基礎(一)-- 執行緒的使用執行緒程式設計
- java多執行緒程式設計:你真的瞭解執行緒中斷嗎?Java執行緒程式設計
- Java多執行緒程式設計筆記9:ReentrantReadWriteLockJava執行緒程式設計筆記
- java多執行緒程式設計chap1-2Java執行緒程式設計
- java多執行緒程式設計chap3-4Java執行緒程式設計
- java多執行緒程式設計chap5-7Java執行緒程式設計
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計
- C#並行,多執行緒程式設計並行集合和PLINQ的例項講解並行執行緒程式設計
- 29. 多執行緒程式設計執行緒程式設計
- 多執行緒程式設計ExecutorService用法執行緒程式設計
- 多執行緒程式設計基礎(二)-- 執行緒池的使用執行緒程式設計
- java8平行計算Java
- Java實驗五: Java多執行緒程式設計(頭歌)Java執行緒程式設計
- 好程式設計師Java培訓分享Java多執行緒程式設計師Java執行緒
- Java併發程式設計:Java執行緒Java程式設計執行緒
- 實驗六 Java多執行緒設計Java執行緒
- 多執行緒程式設計的核心思想執行緒程式設計
- 多執行緒程式設計介紹-條件變數執行緒程式設計變數
- Linux C++ 多執行緒程式設計LinuxC++執行緒程式設計
- iOS開發-多執行緒程式設計iOS執行緒程式設計
- 深入理解多執行緒程式設計執行緒程式設計
- Task+ConcurrentQueue多執行緒程式設計執行緒程式設計
- [02] 多執行緒邏輯程式設計執行緒程式設計
- C#多執行緒程式設計-基元執行緒同步構造C#執行緒程式設計
- C#多執行緒程式設計實戰1.1建立執行緒C#執行緒程式設計
- 多執行緒程式設計總結:一、認識多執行緒本質執行緒程式設計
- Java並行流:一次搞定多執行緒程式設計難題,讓你的程式飛起來!Java並行執行緒程式設計
- 深入淺出Win32多執行緒程式設計--之MFC的多執行緒Win32執行緒程式設計
- Java中的多執行緒程式設計(超詳細總結)Java執行緒程式設計
- 多執行緒程式設計進階——Java類庫中的鎖執行緒程式設計Java
- Java併發程式設計之執行緒安全、執行緒通訊Java程式設計執行緒
- Java基礎之多執行緒程式設計Java執行緒程式設計
- java併發程式設計——執行緒池Java程式設計執行緒