Chinaunix首页 | 论坛 | 博客
  • 博客访问: 155278
  • 博文数量: 17
  • 博客积分: 357
  • 博客等级: 一等列兵
  • 技术积分: 706
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-12 16:49
文章分类

全部博文(17)

文章存档

2013年(3)

2012年(14)

我的朋友

分类: Java

2012-12-08 17:10:58

1进程和线程的概念

什么是进程

一个进程就是在一个运行的程序,它有自己独立的内存空间,一组系统资源,每个进程的内部数据和状态都是独立的,例如在window是同时打开多个记事本,虽然它们所运行的程序代码都是一样的,但是所使用的内存空间是独立的,互不干扰。

1.2什么是线程

线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与进程不同的是,同类的多个线程共享一块内存空间和一组系统资源,而线程本身的数据通常只有微处理器的寄存器数据,以及一个供程序执行时使用的堆栈

1.3进程与线程的区别

1. 进程:每个进程都有独立的代码和数据空间(进程上下文) ,进程切换的开销大。
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

       π=4PN的取值越大,π的值越精确

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<N;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));

       }  

}

 

运行结果比较

 

 

π

Time

多线程(10*10000

2.51108

used time(ms):44

单线程(100000

3.1306

used time(ms):28

 

 

 

π

Time

多线程(100*1000000

3.141768

used time(ms):35203

单线程(100000000

3.1415854

used time(ms):13582

 

根据运行结果看,由于多线程运行时要进行分配资源的操作,在单机上的运行速度并没有单线程效率高。

阅读(3591) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~