进程和线程的概念
什么是进程
一个进程就是在一个运行的程序它有自己独立的内存空间一组系统资源每个进程的内部数据和状态都是独立的例如在window是同时打开多个记事本虽然它们所运行的程序代码都是一样的但是所使用的内存空间是独立的互不干扰
什么是线程
线程与进程相似是一段完成某个特定功能的代码是程序中单个顺序的流控制;但与进程不同的是同类的多个线程共享一块内存空间和一组系统资源而线程本身的数据通常只有微处理器的寄存器数据以及一个供程序执行时使用的堆栈
进程与线程的区别
进程:每个进程都有独立的代码和数据空间(进程上下文) 进程切换的开销大
线程:轻量的进程同一类线程共享代码和数据空间每个线程有独立的运行栈和程序计数器(PC)线程切换的开销小
多进程:在操作系统中能同时运行多个任务程序
多线程:在同一应用程序中有多个顺序流同时执行
线程创建的两种方式
采用继承Thread类创建线程
该方法比较简单主要是通过继承javalangThread类并覆盖Thread类的run()方法来完成线成的创建Thread 类是一个具体的类即不是抽象类该类封装了线程的行为要创建一个线程程序员必须创建一个从 Thread 类导出的新类Thread类中有两个最重要的函数run()和start()
通过实现Runnable接口创建线程
该方法通过生成实现javalangRunnable接口的类该接口只定义了一个方法run()所以必须在新类中实现它但是 Runnable 接口并没有任何对线程的支持我们还必须创建 Thread 类的实例这一点通过 Thread 类的构造函数
public Thread(Runnable target);来实现
单线程和多线程性能比较
以使用蒙特卡罗概率算法求π为例进行单线程和多线程时间比较
什么是蒙特卡罗概率算法
蒙特卡罗法(Monte Carlo method)是以概率和统计的理论方法为基础的一种计算方法将所求解的问题同一定的概率模型相联系用电子计算机实现统计模拟或抽样以获得问题的近似解故又称统计模拟法或统计试验法 百度百科
蒙特卡罗求算法求π
第一步
画正方形和内切圆
第二步
变换表达式
正方形面积As=(R)^
圆的面积Ac=πR^
Ac/As=(R)^/πR^
π=As/Ac
令P=As/Sc则π=P
第三步
重复N次实验求平均值
在正方形区域内随机生成一个点A若A落在圆区域内M++
P=M/N
π=PN的取值越大π的值越精确
java代码实现算法
N取值为万多线程的数为每个线程执行万次模拟实验
线程实现
import ncurrentCountDownLatch;
public class ProModel implements Runnable {
public int N;//随机实验的总次数
public static int M;//随机点落在圆中的次数
private int id;
private final CountDownLatch doneSignal;
OBJ semaphore;
public ProModel(int idCountDownLatch doneSignalint NOBJ semaphore){
thisid=id;
thisdoneSignal=doneSignal;
thisN=N;
thissemaphore=semaphore;
M=;
}
public void run(){
int tempM=;
for(int i=;i<N;i++){
if(isInCircle()){
tempM++;
}
}
synchronized (semaphore) {
add(tempM);
}
untDown();//使end状态减
}
public void add(int tempM){
Systemoutprintln(ThreadcurrentThread()getName());
M=M+tempM;
Systemoutprintln(M);
}
//随机产生一个在正方形区域的点判断它是否在圆中
public boolean isInCircle(){
double x=Mathrandom();
double y=Mathrandom();
if((x)*(x)+(y)*(y)<)
return true;
else
return false;
}
public static int getTotal(){
return M;
}
}
多线程Main实现
import ncurrentCountDownLatch;
import ncurrentExecutorService;
import ncurrentExecutors;
public class MutliThread {
public static void main(String[] args) throws InterruptedException {
long begin=SystemcurrentTimeMillis();
int threadSize=;
int N=;
OBJ semaphore = new OBJ();
CountDownLatch doneSignal = new CountDownLatch(threadSize);
ProModel[] pros=new ProModel[threadSize];
//设置特定的线程池大小为threadSizde
Systemoutprintln(begins!);
ExecutorService exe = ExecutorsnewFixedThreadPool(threadSize);
for(int i=;i<threadSize;i++)
exeexecute(new ProModel(i+doneSignalNsemaphore));
try{
doneSignalawait(); //等待end状态变为 }catch (InterruptedException e) {
// TODO: handle exception
eprintStackTrace();
}finally{
Systemoutprintln(ends!);
Systemoutprintln(*(float)ProModelgetTotal()/(float)(threadSize*N));
}
exeshutdown();
long end=SystemcurrentTimeMillis();
Systemoutprintln(used time(ms):+(endbegin));
}
}
class OBJ{}
单线程Main实现
import ncurrentCountDownLatch;
import ncurrentExecutorService;
import ncurrentExecutors;
public class SingleThread {
public static void main(String[] args) {
long begin=SystemcurrentTimeMillis();
int threadSize=;
int N=;
OBJ semaphore = new OBJ();
CountDownLatch doneSignal = new CountDownLatch(threadSize);
ProModel[] pros=new ProModel[threadSize];
//设置特定的线程池大小为
Systemoutprintln(begins!);
ExecutorService exe = ExecutorsnewFixedThreadPool(threadSize);
for(int i=;i<threadSize;i++)
exeexecute(new ProModel(i+doneSignalNsemaphore));
try{
doneSignalawait(); //等待end状态变为 }catch (InterruptedException e) {
// TODO: handle exception
eprintStackTrace();
}finally{
Systemoutprintln(ends!);
Systemoutprintln(*(float)ProModelgetTotal()/(float)(threadSize*N));
}
exeshutdown();
long end=SystemcurrentTimeMillis();
Systemoutprintln(used time(ms):+(endbegin));
}
}
运行结果比较
根据运行结果看由于多线程运行时要进行分配资源的操作在单机上的运行速度并没有单线程效率高