java线程

备注:温故而知新

什么是进程

进程是处于运行中的程序,并且具有一定的独立功能,是系统进行资源分配和调度的一个独立单位

一般而言,进程包含以下3个特征:

  • 独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每一个进程都拥有自己私有的地址空间,在没有经过进程本身允许的情况下,一个用户进程不可以直接访问其他进程的地址空间。

  • 动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合。在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。

  • 并发性:多个进程可以在单个处理器上并发执行,多个进程不会相互影响

进程和线程的区别

线程则是扩展了进程的概念,使得同一个进程可以同时并发处理多个任务,线程也被称作轻量级进程,是进程的执行单元。

线程与进程的区别:

  • 地址空间: 进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;

  • 资源拥有: 进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源

  • 线程是处理器调度的基本单位,但进程不是.

  • 二者均可并发执行.

进程是系统进行资源分配和调度的一个独立单位。线程是进程的一个实体,是CPU调度和分派的基本单位.

线程不能够单独执行,它必须运行在处于活动状态的应用程序进程中,因此可以定义线程是程序内部的具有并发性的顺序代码流。

线程创建:

  1. 继承 Thread: Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例

  2. 实现Runnable: 如果一个类已经extends另一个类,就无法直接extends Thread,此时,必须实现一个Runnable接口

  3. 使用Callable和future: ExecutorService、Callable、Future这个对象实际上都是属于Executor框架中的功能类

Callable和Runnable的区别如下:

  • Callable定义的方法是call,而Runnable定义的方法是run。
  • Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。
  • Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。
  • 运行Callable任务可拿到一个Future对象。

使用Callable,Future返回结果

Future代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则,get()会使当前线程阻塞。FutureTask实现了Future和Runable。Callable代表一个有返回值得操作。
Callable<Integer> func = new Callable<Integer>(){  
    public Integer call() throws Exception {  
        System.out.println("inside callable");  
        Thread.sleep(1000);  
        return new Integer(8);  
    }         
};        
FutureTask<Integer> futureTask  = new FutureTask<Integer>(func);  
Thread newThread = new Thread(futureTask);  
newThread.start();  

try {  
    System.out.println("blocking here");  
    Integer result = futureTask.get();  
    System.out.println(result);  
} catch (InterruptedException ignored) {  
} catch (ExecutionException ignored) {  
} 

详情可见http://www.iteye.com/topic/366591

ExecutorService 线程池

Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口

  1. newCachedThreadPool() 缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中,缓存型池子通常用于执行一些生存期很短的异步型任务,能reuse的线程,必须是timeout IDLE内的池中线程,缺省timeout是60s,超过这个IDLE时长,线程实例将被终止及移出池。

  2. newFixedThreadPool(int nThreads) newFixedThreadPool与cacheThreadPool差不多,也是能reuse就用,但不能随时建新的线程,其独特之处:任意时间点,最多只能有固定数目的活动线程存在,此时如果有新的线程要建立,只能放在另外的队列中等待,直到当前的线程中某个线程终止直接被移出池子

  3. newSingleThreadPool() 创建一个只有单线程的线程池

  4. newScheduledThreadPool(int corePoolsize) 创建具有指定线程数的线程池,它可以在指定延迟后执行任务,corePoolsize指池中所保持的线程数

  5. newSingleThreadScheduledExecutor() 创建只有一个线程的线程池,它可以在指定延迟后执行线程任务

ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

ThreadPoolExecutor 类

ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue)

ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程调度,线程池管理等等服务; Executors方法提供的线程服务,都是通过参数设置来实现不同的线程池机制。

对应参数介绍:

  • corePoolSize 线程池维护线程的最少数量
  • maximumPoolSize 线程池维护线程的最大数量
  • keepAliveTime 线程池维护线程所允许的空闲时间,终止前多余的空闲线程等待新任务的最长时间
  • unit 空闲时间单位
  • workQueue 线程池所使用的缓冲队列
  • handle 线程池对拒绝任务的处理策略

当一个任务通过execute(Runnable)方法欲添加到线程池时:

如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

详情可见http://825635381.iteye.com/blog/2184680

你可能感兴趣的:(java,java,线程)