java并发之线程池

来源:互联网 发布:航天远景软件 编辑:程序博客网 时间:2024/05/19 15:42

1、java并发介绍

JDK5.0以后都引入了高级并发特性,大多数特性在java.util.concurrent包中,是专门用于多线程并发编程的,充分利用了现代多处理器、多核心的系统的功能以编写大规模并发应用程序。
主要包含原子量、并发集合、同步器、可重入锁、线程池

2、线程池的5种创建方式

1、Single Thread Executor:只有一个线程的线程池,因此所有提交的任务都是顺序执行的。
创建方式:Executors.newSingleThreadExecutor();
2、Cached Thread Pool:线程池里有很多现成需要同步执行,老的可用线程将会被新的任务触发重新执行。如果线程超过60秒内没有执行,那么将被终止并从池中删除。
创建方式:Executors.newCachedThreadPool();

3、Fixed Thread Pool:拥有固定线程数的线程,如果没有任务执行,那么线程将会一直等待。

创建方式:Executors.newFixedThreadPool(4);在构造函数中的参数4是线程池的大小,可以随意设置,也可以和CPU的核数量保持一致。

获取CPU的核数量:int nums = Runtime.getRuntime().availableProcessors();

4、Scheduled Thread Pool:用来调度即将执行的任务的线程池,可能不会直接执行,而是每隔多长时间执行一次----策略型的

创建方式:Executors.newScheduledThreadPool();

3、Runnable与Callable

1)任务实现Runnable接口,调用execute,提交任务,任务完成后Future对象返回null。
这里使用的是固定线程池:FixedThreadPool
public static void main(String[] args) {//创建一个线程池,这里线程池中有两个线程ExecutorService pool = Executors.newFixedThreadPool(2);for(int i = 1; i < 5; i++){pool.execute(new Runnable() {@Overridepublic void run() {System.out.println("thread: " + Thread.currentThread().getName()+",开始执行。。。");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+",完成");}});}pool.shutdown();}
2)任务实现Callable接口,调用submit,提交任务,返回一个Future实例表示任务状态。
该Callable接口中有一个call方法,有返回值,获取返回值会阻塞,一直要等到线程任务返回结果。
/** * callable 跟runnable的区别: * runnable的run方法不会有任何返回结果,所以主线程无法获得任务线程的返回值 *  * callable的call方法可以返回结果,但是主线程在获取时是被阻塞,需要等待任务线程返回才能拿到结果 * @author * */public class ThreadPoolWithcallable {public static void main(String[] args) throws InterruptedException, ExecutionException {ExecutorService pool = Executors.newFixedThreadPool(4); for(int i = 0; i < 10; i++){Future<String> submit = pool.submit(new Callable<String>(){@Overridepublic String call() throws Exception {Thread.sleep(5000);return "b--"+Thread.currentThread().getName();}      });//从Future中get结果,这个方法是会被阻塞的,一直要等到线程任务返回结果System.out.println(submit.get());} pool.shutdown();}}

4、几种线程池的使用

public static void main(String[] args) throws InterruptedException, ExecutionException{//测试CacheThreadPool //ExecutorService service = Executors.newCachedThreadPool();//结论:1、缓存线程池,线程池的大小没有限制,当有任务需要执行,线程池中没有空闲线程,则将会创建新的线程去执行。//2、线程任务执行完成后,不会立即销毁,会等待一定的时间,当有任务执行,则会再次运行//测试SingleThreadPool//ExecutorService service = Executors.newSingleThreadExecutor();//结论:1、单线程池,该线程池中只维护一个线程,当该线程有任务执行,其他任务必须等待该任务的完成,也就相当于串行执行//测试FixedThreadPool,需要执行线程池的大小,即线程的个数,一般指定与当前服务器的cpu的核数有关int nThreads = Runtime.getRuntime().availableProcessors();//ExecutorService service = Executors.newFixedThreadPool(nThreads);//结论:固定线程池:就是线程池的大小是固定的,当有空闲线程时,有任务则执行,若无空闲线程,则任务必须等待。//测试ScheduleThreadPool//对于schedulerPool来说,调用submit提交任务时,跟普通pool效果一致//submit = exec.submit(new TaskCallable(i));//对于schedulerPool来说,调用schedule提交任务时,则可按延迟,按间隔时长来调度线程的运行ScheduledExecutorService service = Executors.newScheduledThreadPool(nThreads);List<Future<String>> fList = new ArrayList<Future<String>>();for(int i = 0 ; i < 10; i ++){//Future<String> future = service.submit(new TaskCallable());//对于schedule方法,有三个参数:参数一:任务,参数二:延迟时间,参数三:延迟时间的单位Future<String> future = service.schedule(new TaskCallable(),5, TimeUnit.SECONDS);fList.add(future);}for(Future<String> future : fList){boolean done = future.isDone();System.out.println(done ? "已完成" : "未完成");System.out.println("执行完成的线程:"+future.get());}service.shutdown();}
public class TaskCallable implements Callable<String>{@Overridepublic String call() throws Exception {String threadName = Thread.currentThread().getName();Random random = new Random();long minit = random.nextInt(5)*1000;Thread.sleep(minit);System.out.println(threadName+":正在执行。。。。。。");return threadName;}}






0 0
原创粉丝点击