完數的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。
實驗加速比與理論加速比相差不大,在誤差允許範圍內可認為結果正確。
相關文章
- 完數的OpenMP並行程式設計-平行計算並行行程程式設計
- 完數的MPI並行程式設計-平行計算並行行程程式設計
- 推薦文章:多執行緒平行計算執行緒
- 淺談.NET下的多執行緒和平行計算(十四)平行計算前言執行緒
- Java執行緒(十一):Fork/Join-Java平行計算框架Java執行緒框架
- 程式設計思想之多執行緒與多程式(3):Java 中的多執行緒程式設計執行緒Java
- 多執行緒程式設計執行緒程式設計
- Java多執行緒程式設計基礎Java執行緒程式設計
- Java多執行緒程式設計要點Java執行緒程式設計
- OpenMP平行計算程式設計-n以內的完數的個數程式設計
- Java多執行緒程式設計—鎖優化Java執行緒程式設計優化
- Java-基礎程式設計-多執行緒Java程式設計執行緒
- java多執行緒程式設計--基礎篇Java執行緒程式設計
- Java多執行緒程式設計要點 (一)Java執行緒程式設計
- Java 多執行緒程式設計要點(synchronized)Java執行緒程式設計synchronized
- Java多執行緒程式設計入門(轉)Java執行緒程式設計
- JavaScript多執行緒程式設計JavaScript執行緒程式設計
- Boost多執行緒程式設計執行緒程式設計
- UNIX多執行緒程式設計執行緒程式設計
- 多執行緒程式設計(轉)執行緒程式設計
- 多執行緒程式設計基礎(一)-- 執行緒的使用執行緒程式設計
- Java多執行緒設計模式(1)Java執行緒設計模式
- 使用執行緒池優化多執行緒程式設計執行緒優化程式設計
- iOS多執行緒程式設計:執行緒同步總結iOS執行緒程式設計
- .NET多執行緒程式設計(3):執行緒同步 (轉)執行緒程式設計
- .NET多執行緒程式設計(1):多工和多執行緒 (轉)執行緒程式設計
- 多執行緒程式設計,處理多執行緒的併發問題(執行緒池)執行緒程式設計
- 實戰體會Java的多執行緒程式設計Java執行緒程式設計
- 淺談.NET下的多執行緒和平行計算系列文章索引執行緒索引
- java多執行緒程式設計chap5-7Java執行緒程式設計
- java多執行緒程式設計chap1-2Java執行緒程式設計
- java多執行緒程式設計chap3-4Java執行緒程式設計
- Java多執行緒程式設計之同步器Java執行緒程式設計
- Java多執行緒程式設計——進階篇一Java執行緒程式設計
- Java多執行緒程式設計——進階篇二Java執行緒程式設計
- 深入淺出Java多執行緒程式設計(轉)Java執行緒程式設計
- 淺析Java多執行緒程式設計機制Java執行緒程式設計
- [短文速讀 -5] 多執行緒程式設計引子:程式、執行緒、執行緒安全執行緒程式設計