Java线程池的几种实现方法和区别介绍

Java线程池的几种实现方法和区别介绍

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class TestThreadPool {
 // -newFixedThreadPool与cacheThreadPool差不多,也是能reuse就用,但不能随时建新的线程
 // -其独特之处:任意时间点,最多只能有固定数目的活动线程存在,此时如果有新的线程要建立,只能放在另外的队列中等待,直到当前的线程中某个线程终止直接被移出池子
 // -和cacheThreadPool不同,FixedThreadPool没有IDLE机制(可能也有,但既然文档没提,肯定非常长,类似依赖上层的TCP或UDP
 // IDLE机制之类的),所以FixedThreadPool多数针对一些很稳定很固定的正规并发线程,多用于服务器
 // -从方法的源代码看,cache池和fixed 池调用的是同一个底层池,只不过参数不同:
 // fixed池线程数固定,并且是0秒IDLE(无IDLE)
 // cache池线程数支持0-Integer.MAX_VALUE(显然完全没考虑主机的资源承受能力),60秒IDLE
 private static ExecutorService fixedService = Executors.newFixedThreadPool(6);
 // -缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中
 // -缓存型池子通常用于执行一些生存期很短的异步型任务
 // 因此在一些面向连接的daemon型SERVER中用得不多。
 // -能reuse的线程,必须是timeout IDLE内的池中线程,缺省timeout是60s,超过这个IDLE时长,线程实例将被终止及移出池。
 // 注意,放入CachedThreadPool的线程不必担心其结束,超过TIMEOUT不活动,其会自动被终止。
 private static ExecutorService cacheService = Executors.newCachedThreadPool();
 // -单例线程,任意时间池中只能有一个线程
 // -用的是和cache池和fixed池相同的底层池,但线程数目是1-1,0秒IDLE(无IDLE)
 private static ExecutorService singleService = Executors.newSingleThreadExecutor();
 // -调度型线程池
 // -这个池子里的线程可以按schedule依次delay执行,或周期执行
 private static ExecutorService scheduledService = Executors.newScheduledThreadPool(10);

 public static void main(String[] args) {
  DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  List<Integer> customerList = new ArrayList<Integer>();
  System.out.println(format.format(new Date()));
  testFixedThreadPool(fixedService, customerList);
  System.out.println("--------------------------");
  testFixedThreadPool(fixedService, customerList);
  fixedService.shutdown();
  System.out.println(fixedService.isShutdown());
  System.out.println("----------------------------------------------------");
  testCacheThreadPool(cacheService, customerList);
  System.out.println("----------------------------------------------------");
  testCacheThreadPool(cacheService, customerList);
  cacheService.shutdownNow();
  System.out.println("----------------------------------------------------");
  testSingleServiceThreadPool(singleService, customerList);
  testSingleServiceThreadPool(singleService, customerList);
  singleService.shutdown();
  System.out.println("----------------------------------------------------");
  testScheduledServiceThreadPool(scheduledService, customerList);
  testScheduledServiceThreadPool(scheduledService, customerList);
  scheduledService.shutdown();
 }

 public static void testScheduledServiceThreadPool(ExecutorService service, List<Integer> customerList) {
  List<Callable<Integer>> listCallable = new ArrayList<Callable<Integer>>();
  for (int i = 0; i < 10; i++) {
   Callable<Integer> callable = new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
     return new Random().nextInt(10);
    }
   };
   listCallable.add(callable);
  }
  try {
   List<Future<Integer>> listFuture = service.invokeAll(listCallable);
   for (Future<Integer> future : listFuture) {
    Integer id = future.get();
    customerList.add(id);
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  System.out.println(customerList.toString());
 }

 public static void testSingleServiceThreadPool(ExecutorService service, List<Integer> customerList) {
  List<Callable<List<Integer>>> listCallable = new ArrayList<Callable<List<Integer>>>();
  for (int i = 0; i < 10; i++) {
   Callable<List<Integer>> callable = new Callable<List<Integer>>() {
    @Override
    public List<Integer> call() throws Exception {
     List<Integer> list = getList(new Random().nextInt(10));
     boolean isStop = false;
     while (list.size() > 0 && !isStop) {
      System.out.println(Thread.currentThread().getId() + " -- sleep:1000");
      isStop = true;
     }
     return list;
    }
   };
   listCallable.add(callable);
  }
  try {
   List<Future<List<Integer>>> listFuture = service.invokeAll(listCallable);
   for (Future<List<Integer>> future : listFuture) {
    List<Integer> list = future.get();
    customerList.addAll(list);
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  System.out.println(customerList.toString());
 }

 public static void testCacheThreadPool(ExecutorService service, List<Integer> customerList) {
  List<Callable<List<Integer>>> listCallable = new ArrayList<Callable<List<Integer>>>();
  for (int i = 0; i < 10; i++) {
   Callable<List<Integer>> callable = new Callable<List<Integer>>() {
    @Override
    public List<Integer> call() throws Exception {
     List<Integer> list = getList(new Random().nextInt(10));
     boolean isStop = false;
     while (list.size() > 0 && !isStop) {
      System.out.println(Thread.currentThread().getId() + " -- sleep:1000");
      isStop = true;
     }
     return list;
    }
   };
   listCallable.add(callable);
  }
  try {
   List<Future<List<Integer>>> listFuture = service.invokeAll(listCallable);
   for (Future<List<Integer>> future : listFuture) {
    List<Integer> list = future.get();
    customerList.addAll(list);
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  System.out.println(customerList.toString());
 }

 public static void testFixedThreadPool(ExecutorService service, List<Integer> customerList) {
  List<Callable<List<Integer>>> listCallable = new ArrayList<Callable<List<Integer>>>();
  for (int i = 0; i < 10; i++) {
   Callable<List<Integer>> callable = new Callable<List<Integer>>() {
    @Override
    public List<Integer> call() throws Exception {
     List<Integer> list = getList(new Random().nextInt(10));
     boolean isStop = false;
     while (list.size() > 0 && !isStop) {
      System.out.println(Thread.currentThread().getId() + " -- sleep:1000");
      isStop = true;
     }
     return list;
    }
   };
   listCallable.add(callable);
  }
  try {
   List<Future<List<Integer>>> listFuture = service.invokeAll(listCallable);
   for (Future<List<Integer>> future : listFuture) {
    List<Integer> list = future.get();
    customerList.addAll(list);
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  System.out.println(customerList.toString());
 }

 public static List<Integer> getList(int x) {
  List<Integer> list = new ArrayList<Integer>();
  list.add(x);
  list.add(x * x);
  return list;
 }
}

使用:LinkedBlockingQueue实现线程池讲解

//例如:corePoolSize=3,maximumPoolSize=6,LinkedBlockingQueue(10)

//RejectedExecutionHandler默认处理方式是:ThreadPoolExecutor.AbortPolicy

//ThreadPoolExecutor executorService = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, 1L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(10));

//1.如果线程池中(也就是调用executorService.execute)运行的线程未达到LinkedBlockingQueue.init(10)的话,当前执行的线程数是:corePoolSize(3) 

//2.如果超过了LinkedBlockingQueue.init(10)并且超过的数>=init(10)+corePoolSize(3)的话,并且小于init(10)+maximumPoolSize. 当前启动的线程数是:(当前线程数-init(10))

//3.如果调用的线程数超过了init(10)+maximumPoolSize 则根据RejectedExecutionHandler的规则处理。

关于:RejectedExecutionHandler几种默认实现讲解

//默认使用:ThreadPoolExecutor.AbortPolicy,处理程序遭到拒绝将抛出运行时RejectedExecutionException。
			RejectedExecutionHandler policy=new ThreadPoolExecutor.AbortPolicy();
//			//在 ThreadPoolExecutor.CallerRunsPolicy 中,线程调用运行该任务的execute本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。
//			policy=new ThreadPoolExecutor.CallerRunsPolicy();
//			//在 ThreadPoolExecutor.DiscardPolicy 中,不能执行的任务将被删除。
//			policy=new ThreadPoolExecutor.DiscardPolicy();
//			//在 ThreadPoolExecutor.DiscardOldestPolicy 中,如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)。
//			policy=new ThreadPoolExecutor.DiscardOldestPolicy();

以上这篇Java线程池的几种实现方法和区别介绍就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java代码构建一个线程池

    在现代的操作系统中,有一个很重要的概念――线程,几乎所有目前流行的操作系统都支持线程,线程来源于操作系统中进程的概念,进程有自己的虚拟地址空间以及正文段.数据段及堆栈,而且各自占有不同的系统资源(例如文件.环境变量等等).与此不同,线程不能单独存在,它依附于进程,只能由进程派生.如果一个进程派生出了两个线程,那这两个线程共享此进程的全局变量和代码段,但每个线程各拥有各自的堆栈,因此它们拥有各自的局部变量,线程在UNIX系统中还被进一步分为用户级线程(由进程自已来管理)和系统级线程(由操作系统的调

  • 支持生产阻塞的Java线程池

    通常来说,生产任务的速度要大于消费的速度.一个细节问题是,队列长度,以及如何匹配生产和消费的速度. 一个典型的生产者-消费者模型如下:   在并发环境下利用J.U.C提供的Queue实现可以很方便地保证生产和消费过程中的线程安全.这里需要注意的是,Queue必须设置初始容量,防止生产者生产过快导致队列长度暴涨,最终触发OutOfMemory. 对于一般的生产快于消费的情况.当队列已满时,我们并不希望有任何任务被忽略或得不到执行,此时生产者可以等待片刻再提交任务,更好的做法是,把生产者阻塞在提交任

  • Java线程池使用与原理详解

    线程池是什么? 我们可以利用java很容易创建一个新线程,同时操作系统创建一个线程也是一笔不小的开销.所以基于线程的复用,就提出了线程池的概念,我们使用线程池创建出若干个线程,执行完一个任务后,该线程会存在一段时间(用户可以设定空闲线程的存活时间,后面会介绍),等到新任务来的时候就直接复用这个空闲线程,这样就省去了创建.销毁线程损耗.当然空闲线程也会是一种资源的浪费(所有才有空闲线程存活时间的限制),但总比频繁的创建销毁线程好太多. 下面是我的测试代码 /* * @TODO 线程池测试 */ @

  • Java Socket编程实例(三)- TCP服务端线程池

    一.服务端回传服务类: import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.util.logging.Level; import java.util.logging.Logger; public class EchoProtocol implements Runnable { private static f

  • 详谈Java几种线程池类型介绍及使用方法

    一.线程池使用场景 •单个任务处理时间短 •将需处理的任务数量大 二.使用Java线程池好处 1.使用new Thread()创建线程的弊端: •每次通过new Thread()创建对象性能不佳. •线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom. •缺乏更多功能,如定时执行.定期执行.线程中断. 2.使用Java线程池的好处: •重用存在的线程,减少对象创建.消亡的开销,提升性能. •可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞

  • 深入java线程池的使用详解

    在Java 5.0之前启动一个任务是通过调用Thread类的start()方法来实现的,任务的提于交和执行是同时进行的,如果你想对任务的执行进行调度或是控制 同时执行的线程数量就需要额外编写代码来完成.5.0里提供了一个新的任务执行架构使你可以轻松地调度和控制任务的执行,并且可以建立一个类似数据库连接 池的线程池来执行任务.这个架构主要有三个接口和其相应的具体类组成.这三个接口是Executor, ExecutorService.ScheduledExecutorService,让我们先用一个图

  • java中通用的线程池实例代码

    复制代码 代码如下: package com.smart.frame.task.autoTask; import java.util.Collection;import java.util.Vector; /** * 任务分发器 */public class TaskManage extends Thread{    protected Vector<Runnable> tasks = new Vector<Runnable>();    protected boolean run

  • Java 线程池详解及实例代码

    线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收. 所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁.如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些"池化资源"技术产生的原因. 例如Android中常见到的很多通用组件一般都离不开"池"的概念,如各种图片

  • Java 线程池ExecutorService详解及实例代码

    Java 线程池ExecutorService 1.线程池 1.1什么情况下使用线程池 单个任务处理的时间比较短. 将需处理的任务的数量大. 1.2使用线程池的好处 减少在创建和销毁线程上所花的时间以及系统资源的开销. 如果不使用线程池,有可能造成系统创建大量线程而导致消耗系统内存以及"过度切换"; 2.ExecutorService和Executors 2.1简介 ExecutorService是一个接口,继承了Executor, public interface ExecutorS

  • 四种Java线程池用法解析

    本文为大家分析四种Java线程池用法,供大家参考,具体内容如下 1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } } ).start(); 那你就out太多了,new Thread的弊端如下: a. 每次new Thread新建对象性能差. b. 线程缺乏统一管理,可能无限

随机推荐