單多線程Java算法相比較
1進程和線程的概念
1.1什么是進程
一個進程就是在一個運行的程序,它有自己獨立的內存空間,一組系統資源,每個進程的內部數據和狀態都是獨立的,例如在window是同時打開多個記事本,雖然它們所運行的程序代碼都是一樣的,但是所使用的內存空間是獨立的,互不干擾.
1.2什么是線程
線程與進程相似,是一段完成某個特定功能的代碼,是程序中單個順序的流控制;但與進程不同的是,同類的多個線程共享一塊內存空間和一組系統資源,而線程本身的數據通常只有微處理器的寄存器數據,以及一個供程序執行時使用的堆棧
1.3進程與線程的區別
1. 進程:每個進程都有獨立的代碼和數據空間(進程上下文) ,tb進程切換的開銷大.
2. 線程:輕量的進程,同一類線程共享代碼和數據空間,每個線程有獨立的運行棧和程序計數器(PC),線程切換的開銷小.
3. 多進程:在操作系統中,能同時運行多個任務程序.
4. 多線程:在同一應用程序中,有多個順序流同時執行.
1.4線程創建的兩種方式
采用繼承Thread類創建線程
該方法比較簡單,主要是通過繼承java.lang.Thread類,并覆蓋Thread類的run()方法來完成線成的創建.Thread 類是一個具體的類,即不是抽象類,該類封裝了線程的行為.要創建一個線程,程序員必須創建一個從 Thread 類導出的新類.Thread類中有兩個最重要的函數run()和start().
通過實現Runnable接口創建線程
該方法通過生成實現java.lang.Runnable接口的類.該接口只定義了一個方法run(),所以必須在新類中實現它.但是 Runnable 接口并沒有任何對線程的支持,我們還必須創建 Thread 類的實例,這一點通過 Thread 類的構造函數
public Thread(Runnable target);來實現.
2 單線程和多線程性能比較
以使用蒙特卡羅概率算法求π為例,進行單線程和多線程時間比較
2.1什么是蒙特卡羅概率算法
蒙特卡羅法(Monte Carlo method)是以概率和統計的理論、方法為基礎的一種計算方法,將所求解的問題同一定的概率模型相聯系,用電子計算機實現統計模擬或抽樣,以獲得問題的近似解,故又稱統計模擬法或統計試驗法. --百度百科
蒙特卡羅求算法求π
第一步
畫正方形和內切圓
第二步
變換表達式
正方形面積As=(2R)^2
圓的面積Ac=πR^2
Ac/As=(2R)^2/πR^2
π=4As/Ac
令P=As/Sc,則π=4P
第三步
重復N次實驗求平均值
在正方形區域內隨機生成一個點A,若A落在圓區域內,M++
P=M/N
π=4P,N的取值越大,π的值越精確
2.2 java代碼實現算法
N取值為10000萬,多線程的數為100,每個線程執行100萬次模擬實驗
線程實現
import java.util.concurrent.CountDownLatch;
public class ProModel implements Runnable {
public int N;//隨機實驗的總次數
public static int M;//隨機點落在圓中的次數
private int id;
private final CountDownLatch doneSignal;
OBJ semaphore;
public ProModel(int id,CountDownLatch doneSignal,int N,OBJ semaphore2){
this.id=id;
this.doneSignal=doneSignal;
this.N=N;
this.semaphore=semaphore2;
M=0;
}
public void run(){
int tempM=0;
for(int i=0;i
if(isInCircle()){
tempM++;
}
}
synchronized (semaphore) {
add(tempM);
}
doneSignal.countDown();//使end狀態減1
}
public void add(int tempM){
System.out.println(Thread.currentThread().getName());
M=M+tempM;
System.out.println(M);
}
//隨機產生一個在正方形區域的點,判斷它是否在圓中
public boolean isInCircle(){
double x=Math.random();
double y=Math.random();
if((x-0.5)*(x-0.5)+(y-0.5)*(y-0.5)<0.25)
return true;
else
return false;
}
public static int getTotal(){
return M;
}
}
多線程Main實現
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MutliThread {
public static void main(String[] args) throws InterruptedException {
long begin=System.currentTimeMillis();
int threadSize=100;
int N=1000000;
OBJ semaphore = new OBJ();
CountDownLatch doneSignal = new CountDownLatch(threadSize);
ProModel[] pros=new ProModel[threadSize];
//設置特定的線程池,大小為threadSizde
System.out.println(“begins!”);
ExecutorService exe = Executors.newFixedThreadPool(threadSize);
for(int i=0;i
exe.execute(new ProModel(i+1,doneSignal,N,semaphore));
try{
doneSignal.await(); //等待end狀態變為0, }catch (InterruptedException e) {
// TODO: handle exception35
e.printStackTrace();
}finally{
System.out.println(“ends!”);
System.out.println(4*(float)ProModel.getTotal()/(float)(threadSize*N));
}
exe.shutdown();
long end=System.currentTimeMillis();
System.out.println(“used time(ms):”+(end-begin));
}
}
class OBJ{}
單線程Main實現
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThread {
public static void main(String[] args) {
long begin=System.currentTimeMillis();
int threadSize=1;
int N=100000000;
OBJ semaphore = new OBJ();
CountDownLatch doneSignal = new CountDownLatch(threadSize);
ProModel[] pros=new ProModel[threadSize];
//設置特定的線程池,大小為5
System.out.println(“begins!”);
ExecutorService exe = Executors.newFixedThreadPool(threadSize);
for(int i=0;i
exe.execute(new ProModel(i+1,doneSignal,N,semaphore));
try{
doneSignal.await(); //等待end狀態變為0, }catch (InterruptedException e) {
// TODO: handle exception35
e.printStackTrace();
}finally{
System.out.println(“ends!”);
System.out.println(4*(float)ProModel.getTotal()/(float)(threadSize*N));
}
exe.shutdown();
long end=System.currentTimeMillis();
System.out.println(“used time(ms):”+(end-begin));
}
}