java线程池

1:线程池类为 java.util.concurrent.ThreadPoolExecutor,

 

常用构造方法为:ThreadPoolExecutor(int corePoolSize,  int maximumPoolSize,  long keepAliveTime,   TimeUnit , unitBlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) 

 

corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略

corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略

 

一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。

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

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

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

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

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。

也就是:处理任务的优先级为:
核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

 

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

 

unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。

 

workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue

 

handler有四个选择:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务

 

一般用法举例:

import java.util.concurrent.ArrayBlockingQueue;    
import java.util.concurrent.ThreadPoolExecutor;    
import java.util.concurrent.TimeUnit;    
   
public class TestThreadPool2 {    
    private static int produceTaskSleepTime = 2;    
        
    private static int produceTaskMaxNumber = 10;    
   
    public static void main(String[] args) {    
   
    //构造一个线程池    
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,    
    TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),    
    new ThreadPoolExecutor.DiscardOldestPolicy());    
   
    for(int i=1;i<=produceTaskMaxNumber;i++){    
    try {    
    //产生一个任务,并将其加入到线程池    
    String task = "task@ " + i;    
    System.out.println("put " + task);    
    threadPool.execute(new ThreadPoolTask(task));    
   
    //便于观察,等待一段时间    
    Thread.sleep(produceTaskSleepTime);    
    } catch (Exception e) {    
    e.printStackTrace();    
    }    
    }    
    }    
}    
   
import java.io.Serializable;    
   
public class ThreadPoolTask implements Runnable, Serializable {    
   
    private static final long serialVersionUID = 0;    
    private static int consumeTaskSleepTime = 2000;    
    //保存任务所需要的数据    
    private Object threadPoolTaskData;    
   
    ThreadPoolTask(Object tasks){    
    this.threadPoolTaskData = tasks;    
    }    
    public void run(){    
    //处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句    
    System.out.println(Thread.currentThread().getName());       
    System.out.println("start .."+threadPoolTaskData);    
        
    try {    
    ////便于观察,等待一段时间    
    Thread.sleep(consumeTaskSleepTime);    
    } catch (Exception e) {    
    e.printStackTrace();    
    }    
    threadPoolTaskData = null;    
    }    
        
    public Object getTask(){    
    return this.threadPoolTaskData;    
    }    
    }    

 

 

2:类Executors,此类中提供的一些静态方法有:

    1,public static ExecutorServic newCachedThreadPool(),创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。

    2,public static ExecutorServic newFixedThreadPool(int nThreads),创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。

    3,public static ExecutorService newSingleThreadExecutor(),创建一个使用单个worker 线程的 Executor,以无界队列方式来运行该线程。
   
这三个方法都可以配合接口ThreadFactory的实例一起使用。并且返回一个ExecutorService接口的实例
接口TreadFactory
根据需要创建新线程的对象。使用线程工厂就无需再手工编写对 new Thread 的调用了,从而允许应用程序使用特殊的线程子类、属性等等。
此接口最简单的实现就是:
class SimpleThreadFactory implements ThreadFactory {
   public Thread newThread(Runnable r) {
     return new Thread(r);
   }
 } 
 
例:
//创建一个Runnable接口的线程
 
public class MyThread implements Runnable {
    private int count = 1, number;
 
    public MyThread(int num) {
       number = num;
       System.out.println("Create Thread-" + number);
    }
 
    public void run() {
       while (true) {
           System.out.println("Thread-" + number + " run " + count+" time(s)");
           if (++count == 3)
              return;
       }
    }
}

//使用newSingleThreadExecutor启动线程 
public class SingleThreadExecutor {
    public static void main(String[] args) {
       ExecutorService exec = Executors.newSingleThreadExecutor();
       for (int i = 0; i < 5; i++)
           exec.execute(new MyThread(i));
       exec.shutdown();
    }
}
 

 配合TreadFactory的使用:

 

//设置后台线程属性
public class DaemonThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
       Thread t = new Thread(r);
       t.setDaemon(true);
       return t;
    }
}
//设置最高优先级属性
public class MaxPriorityThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
       Thread t = new Thread(r);
       t.setPriority(Thread.MAX_PRIORITY);
       return t;
    }
}
//设置最低优先级属性
public class MinPriorityThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
       Thread t = new Thread(r);
       t.setPriority(Thread.MIN_PRIORITY);
       return t;
    }
}
//启动带有属性设置的线程
public class ExecFromFactory {
    public static void main(String[] args) throws Exception {
       ExecutorService defaultExec = Executors.newCachedThreadPool();
       ExecutorService daemonExec = Executors
              .newCachedThreadPool(new DaemonThreadFactory());
       ExecutorService maxPriorityExec = Executors
              .newCachedThreadPool(new MaxPriorityThreadFactory());
       ExecutorService minPriorityExec = Executors
              .newCachedThreadPool(new MinPriorityThreadFactory());
       for (int i = 0; i < 10; i++)
           daemonExec.execute(new MyThread(i));
       for (int i = 10; i < 20; i++)
           if (i == 10)
              maxPriorityExec.execute(new MyThread(i));
           else if (i == 11)
              minPriorityExec.execute(new MyThread(i));
           else
              defaultExec.execute(new MyThread(i));
    }
}

 

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