多线程基础准备

进程:程序的执行过程,持有资源和线程

线程:是系统中最小的执行单元,同一个进程可以有多个线程,线程共享进程资源

线程交互(同步synchronized):包括互斥和协作,互斥通过对象锁实现,协作是多线程竞争同一资源时用wait和notify配合协作

  需要注意的是互斥和协作的前提是同一资源,如果多个线程之间没有对同一个资源进行竞争,那么不叫线程交互,叫多线程就好了。

线程状态:

创建状态---创建一个新线程

就虚状态---start(),等待cpu资源

运行状态---执行run()方法

阻塞状态---线程暂停,如sleep,wait等触发

终止状态---线程销毁

这些东西都是干货,看起来都很熟悉,但是真正使用的时候会出现各种各样的问题,多写几个ThreadDemo就好了,只是抛砖引玉吧。

 

线程池

作用:限制系统执行线程的数量

为什么要用线程池:

1,减少线程创建和销毁的次数,线程创建和销毁的消耗的资源和时间也不可忽略,可能创建和销毁的时间大于任务的执行时间呢!一次创建,多次使用。

2,根据系统的承受能力,合理控制线程数量,防止无限不合理消耗内存,使服务器死机,一个线程大概要使用1M的内存。

用到的几个重要的类:

1,Executor---线程池顶级接口,执行线程的工具接口,并非线程池

2,ExecutorService---线程池接口

3,ScheduleExecutorService---和Timer/TimerTask类似,解决任务需要重复执行的问题

4,ThreadPoolExecutor---ExecutorService的默认实现类

5,ScheduleThreadPollExecutor---继承ThreadPoolExecutor的ScheduleExecutorService接口的实现类

常用线程池:

1,SingleThreadExecutor,单线程的线程池,也就是一个线程串行执行全部任务。

2,FixedThreadPool,固定大小的线程池,每次提交一个任务先判断核心线程是否已经满了,没满则创建一个新的线程执行任务,满了判断执行队列是否满了,没满把任务放在执行队列,满了判断线程池是否已经满了,没满创建一个新的线程执行任务,满了交给策略处理,如下图:

    

3,CacheThreadPool,可缓存的线程池,如果线程大小超过了任务需要的线程,就会回收部分空闲线程,当任务量增加时,线程池可以智能的添加新线程来处理任务,对线程的数量不做限制。

4,ScheduleThreadPool,无限大小的线程池,可以定时及周期性执行任务。

ThreadPoolExecutor构造方法参数解释

构造方法

new ThreadPoolExecutor(CORE_POOL_SIZE,  MAXIMUM_POOL_SIZE, KEEP_ALIVE, UNIT, WORK_QUEUE, THREAD_FACTORY);

参数解释

CORE_POOL_SIZE --- 核心线程数

MAXIMUM_POOL_SIZE --- 最大线程数

KEEP_ALIVE --- 大于核心线程数的空闲线程等待新任务的时间

UNIT --- KEEP_ALIVE的时间单位

WORK_QUEUE --- 执行队列

THREAD_FACTORY --- 创建新执行任务的工厂

 

示例线程池代码:

public class ThreadPoolExample{
    private static final int CORE_POOL_SIZE = 3;
    private static final int MAXIMUM_POOL_SIZE = 10;
    private static final int KEEP_ALIVE = 10;

    private static final BlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingQueue<Runnable>(10);
    private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {  
        public Thread newThread(Runnable r) {
            return new Thread(r);
        }
    };
    private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE,
            MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, WORK_QUEUE, THREAD_FACTORY);
    //提交任务
    public void submitTask(Runnable r){
        WORK_QUEUE.add(THREAD_FACTORY.newThread(r));
        //执行排在首位的任务
        THREAD_POOL_EXECUTOR.execute(WORK_QUEUE.poll());
    }
    
    public static void main(String[] args) {
        Runnable r = new Runnable(){
            public void run(){
                System.out.println("线程开始。。");
            }
        };
        //调用
        new ThreadPoolExample().submitTask(r);
    }
    
}

 

公司不用线程池,就先这样简单的理解一下吧~

 

posted on 2016-03-15 17:44  Frand.D  阅读(221)  评论(0编辑  收藏  举报