利用java的多线程编程可以大大的提高系统的并发运行效率,线程越多并发执行的任务就越多,但是并不意味着效率会一直提高,相反会得到适得其反的效果。

  java中的多线程编程一共有三种方法:

    继承Thread类

    继承Runnable接口

    使用线程池Executor

  下面简单的介绍一些Executor的使用

 一、话不多说先上代码:

  创建一个线程数为3的线程池,模拟十个任务让线程池调度线程去完成。

 package executorExample;

 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Threads{
private static final int nThreads = 3;
private int i;
public void Thread(){
//实现ExecutorService接口创建 线程数为三个的线程池
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
for (i = 0; i < 10; i++) {
//在匿名内部类中变量index还在必须把index声明成final类型
final int index = i;
executorService.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
String threadName = Thread.currentThread().getName();//获取当前线程的名字
System.out.println(threadName+"正在执行任务:"+index);
}
});
}
}
public static void main(String[] args){
Threads thread = new Threads();
thread.Thread();
}
}

  接下来解释一下这段代码。在这段代码当中用到的关键词有ExcutorService,Executors,newFixedThreadPool和execute方法,还有一个最重要的Executor,现在来解释一下他们之间的关系

1、Executors

  首先我们先看一下Executors的源码

 public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());

public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
    return new FinalizableDelegatedExecutorService
      (new ThreadPoolExecutor(1, 1,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>(),
                    threadFactory));
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}

  里面有四种都是ExecutorService类型的线程池,也就是说,我们在创建线程池的时候可以有四种选择,newCachedThreadPool,newFixedThreadPool,newSingleThreadExecutor,newWorkStealingPool。其中最常用的就是newCatchedThreadPool和newFixedThreadPool,可以看到每个线程池的参数队列是不同的,LinkedBlockingQueue<Runnable>()属于无边界队列,

  (1)newFixedThreadPool

    是一个固定线程数的线程池,当线程池里线程满了之后,下载任务就会被阻塞到等待下载队列里面等待下载。而LinkedBlockingQueue<Runnable>()无限扩容的FIFO规则的队列,我们在编程的时候一般用它比较多。

  (2)newCatchedThreadPool

    是一个可缓存线程池,如果线程池里的线程数超过了处理需要,则线程池可以灵活的回收空闲的线程,

  别的线程池就先不介绍了

2、ExecutorService

 public interface ExecutorService extends Executor {

  在接口ExecutorService的源码中我们可以看到继承了Executor类,并且在ExecutorService方法中实现了

    

void shutdown();
invokeAll();
submit();

  等等的方法。

3、Executor

 public interface Executor {

     void execute(Runnable command);
}

  在接口Executor中只有一个execute()方法,这是用来将任务提交给线程的。

到这里就明白了他们之间的关系,这样可以帮助我们更好的利用线程池去提高我们的代码效率。

写的不是很完善,如果有大神,希望多多指教,写这个东西也是为了自己能够更熟练的使用线程池。

java线程池的创建使用的更多相关文章

  1. Java线程池的创建详解

    本篇文章主要总结了Java创建线程池的三种方式以及线程池参数的详细说明,对线程池感兴趣的同学可以作为参考学习. 1)通过工具类java.util.concurrent.Executors的静态方法来创 ...

  2. JAVA线程池的创建与使用

    为什么要用线程池? 我们都知道,每一次创建一个线程,JVM后面的工作包括:为线程建立虚拟机栈.本地方法栈.程序计数器的内存空间(下图可看出),所以线程过多容易导致内存空间溢出.同时,当频繁的创建和销毁 ...

  3. java线程池及创建多少线程合适

    java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...

  4. java 线程池的创建方式

    package com.nf147.Constroller; import java.util.concurrent.ExecutorService; import java.util.concurr ...

  5. JAVA线程池的创建

    /** * 创建不同类型的线程池 Executors * * @author */ public class ThreadPoolTest01 { public static void main(St ...

  6. Java线程池的那些事

    熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...

  7. 使用Java 线程池的利弊及JDK自带六种创建线程池的方法

    1. 为什么使用线程池 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过网络协 ...

  8. Java线程池解析

    Java的一大优势是能完成多线程任务,对线程的封装和调度非常好,那么它又是如何实现的呢? jdk的包下和线程相关类的类图. 从上面可以看出Java的线程池主的实现类主要有两个类ThreadPoolEx ...

  9. Java 线程池框架核心代码分析--转

    原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...

随机推荐

  1. 附录三 关于book.h

    本书中用到的公用函数放到了头文件book.h中. #ifndef __BOOK_H__ #define __BOOK_H__ #include <stdio.h> #include < ...

  2. css英文字符或者数字不换行的问题

    table-layout:fixed; word-break: break-all; overflow:hidden;

  3. Node.js Web 模块

    什么是 Web 服务器? Web服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,Web服务器的基本功能就是提供Web信息浏览服务.它只需支持HTTP协议.HTML文档格式及URL,与客 ...

  4. oracle 归档模式开启后数据库宕机解决过程

    首先按照网友说的shutdown immediately,结果hang了半个小时也么反应. 然后检查日志,全盘搜索.trc,发现 (D:\app\oracle\diag\rdbms\cms1u\cms ...

  5. robotframework自动化系列:新增流程

    刚接手项目的时候,要求所有流程在上线之前必须确保正向操作是正确的:这个时候又有新的模块需要测试,所以引入自动化测试是非常有必要的!通过对比,尝试使用RF进行自动化的回归测试. 测试中最常见的操作就是增 ...

  6. 对比MFC和Winform及WPF

    MFC 生成本机代码,自然是很快.可是,消息循环,减缓了界面显示速度.winform 封装了 win32 的api,多次进行P/invoke 操作 (大部分使用p/invoke操作封装),速度慢 .w ...

  7. c++ const全局对象是如何处理的

    我主要是记录一个发现,目前我不能解释,先作个记录. const 只是一个 语义约束,由编译器强制实施的.使被约束的对象不能被直接访问修改. 我用 『直接』这词,因为在代码段中 ,用一个const 指针 ...

  8. 原生JS—实现图片循环切换及监测鼠标滚动切换图片

    今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法以及如何检测鼠标滚动循环切换图片.多余的话我们就不多说了,我们一个一个开始讲吧. 1  原生JS实现图片循环切换 -- 方法一 在上栗子之前我们 ...

  9. HTTP协议类

    本文从以下几方面介绍HTTP协议 HTTP协议的主要特点 HTTP报文的组成部分 HTTP方法 HTTP状态码 POST和GET的区别 什么是持久连接 什么是管线化 主要特点: http协议的特点: ...

  10. LKD: Chapter 6 Kernel Data Structures

    这一章我们研究四种主要的数据结构: linked lists, queues, maps, binary trees. Linked Lists:(<linux/list.h>) 在lin ...