线程池;java的线程池的实现原理;适用于频繁互动(如电商网站)

线程池是一种多线程处理形式,处理过程中将任务加入到队列,然后在创建线程后自己主动启动这些任务。线程池线程都是后台线程。每一个线程都使用默认的堆栈大小,以默认的优先级执行。并处于多线程单元中。

假设某个线程在托管代码中空暇(如正在等待某个事件),则线程池将插入还有一个辅助线程来使全部处理器保持繁忙。

假设全部线程池线程都始终保持繁忙,但队列中包括挂起的工作,则线程池将在一段时间后创建还有一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程能够排队,但他们要等到其它线程完毕后才启动。

组成部分

1、线程池管理器(ThreadPoolManager):用于创建并管理线程池

2、工作线程(WorkThread): 线程池中线程

3、任务接口(Task):每一个任务必须实现的接口。以供工作线程调度任务的运行。

4、任务队列:用于存放没有处理的任务。提供一种缓冲机制。

技术背景编辑

在面向对象编程中,创建和销毁对象是非常费时间的,由于创建一个对象要获取内存资源或者其他很多其他资源。在Java中更是如此,虚拟机将试图跟踪每个对象。以便可以在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能降低创建和销毁对象的次数,特别是一些非常耗资源的对象创建和销毁。

怎样利用已有对象来服务就是一个须要解决的关键问题,事实上这就是一些"池化资源"技术产生的原因。比方大家所熟悉的数据库连接池正是遵循这一思想而产生的,本文将介绍的线程池技术相同符合这一思想。

眼下,一些著名的大公司都特别看好这项技术,并早已经在他们的产品中应用该技术。比方IBM的WebSphere,IONA的Orbix 2000在SUN的 Jini中,Microsoft的MTS(Microsoft Transaction Server 2.0),COM+等。

4功能编辑

应用程序能够有多个线程。这些线程在休眠状态中须要耗费大量时间来等待事件发生。

其它线程可能进入睡眠状态,而且仅定期被唤醒以轮循更改或更新状态信息,然后再次进入休眠状态。为了简化对这些线程的管理,.NET框架为每一个进程提供了一个线程池,一个线程池有若干个等待操作状态。当一个等待操作完毕时,线程池中的辅助线程会运行回调函数。线程池中的线程由系统管理。程序猿不须要费力于线程管理,能够集中精力处理应用程序任务。

应用范围fr=aladdin#" class="nslog:1019" title="编辑本段" style="text-decoration:none; color:rgb(136,136,136); height:15px; line-height:16px; padding-left:18px; background-color:transparent; font-size:12px; font-family:宋体; display:block">编辑

1、须要大量的线程来完毕任务。且完毕任务的时间比較短。

WEBserver完毕网页请求这种任务,使用线程池技术是很合适的。由于单个任务小,而任务数量巨大,你能够想象一个热门站点的点击次数。 但对于长时间的任务。比方一个Telnet连接请求,线程池的长处就不明显了。由于Telnet会话时间比线程的创建时间大多了。

2、对性能要求苛刻的应用,比方要求server迅速响应客户请求。

3、接受突发性的大量请求,但不至于使server因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,尽管理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,并出现"OutOfMemory"的错误。

Java线程池原理及实现

简介

创建线程有两种方式:继承Thread或实现Runnable。

Thread实现了Runnable接口。提供了一个空的run()方法。所以不论是继承Thread还是实现Runnable,都要有自己的run()方法。

一个线程创建后就存在。调用start()方法就開始执行(执行run()方法)。调用wait进入等待或调用sleep进入休眠期,顺利执行完成或休眠被中断或执行过程中出现异常而退出。

wait和sleep比較:

sleep方法有:sleep(long millis),sleep(long millis, long nanos),调用sleep方法后,当前线程进入休眠期,暂停运行,但该线程继续拥有监视资源的全部权。到达休眠时间后线程将继续运行,直到完毕。若在休眠期还有一线程中断该线程。则该线程退出。

wait方法有:wait(),wait(long timeout),wait(long timeout, long nanos)。调用wait方法后,该线程放弃监视资源的全部权进入等待状态;

wait():等待有其他的线程调用notify()或notifyAll()进入调度状态。与其他线程共同争夺监视。wait()相当于wait(0),wait(0, 0)。

wait(long timeout):当其他线程调用notify()或notifyAll()。或时间到达timeout亳秒,或有其他某线程中断该线程。则该线程进入调度状态。

wait(long timeout, long nanos):相当于wait(1000000*timeout + nanos)。仅仅只是时间单位为纳秒。

线程池:

多线程技术主要解决处理器单元内多个线程运行的问题。它能够显著降低处理器单元的闲置时间。添加处理器单元的吞吐能力。

如果一个server完毕一项任务所需时间为:T1 创建线程时间,T2 在线程中运行任务的时间,T3 销毁线程时间。

假设:T1 + T3 远大于 T2,则能够採用线程池。以提高server性能。

一个线程池包含下面四个基本组成部分:

1、线程池管理器(ThreadPool):用于创建并管理线程池。包含 创建线程池,销毁线程池,加入新任务;

2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态。能够循环的运行任务;

3、任务接口(Task):每一个任务必须实现的接口,以供工作线程调度任务的运行。它主要规定了任务的入口。任务运行完后的收尾工作,任务的运行状态等。

4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

线程池技术正是关注怎样缩短或调整T1,T3时间的技术。从而提高server程序性能的。它把T1,T3分别安排在server程序的启动和结束的时间段或者一些空暇的时间段,这样在server程序处理客户请求时,不会有T1,T3的开销了。

线程池不仅调整T1,T3产生的时间段。并且它还显著降低了创建线程的数目,看一个样例:

如果一个server一天要处理50000个请求,而且每一个请求须要一个单独的线程完毕。在线程池中,线程数通常是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果server不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的server程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。

/** 线程池类。工作线程作为其内部类 **/

import java.util.Collections;

import java.util.Date;

import java.util.LinkedList;

import java.util.List;

import org.apache.log4j.Logger;

/**

* 线程池

* 创建线程池,销毁线程池,加入新任务

*

* @author obullxl

*/

public final class ThreadPool {

private static Logger logger = Logger.getLogger(ThreadPool.class);

private static Logger taskLogger = Logger.getLogger("TaskLogger");

private static boolean debug = taskLogger.isDebugEnabled();

// private static boolean debug = taskLogger.isInfoEnabled();

/* 单例 */

private static ThreadPool instance = ThreadPool.getInstance();

public static final int SYSTEM_BUSY_TASK_COUNT = 150;

/* 默认池中线程数 */

public static int worker_num = 5;

/* 已经处理的任务数 */

private static int taskCounter = 0;

public static boolean systemIsBusy = false;

private static List<Task> taskQueue = Collections

.synchronizedList(new LinkedList<Task>());

/* 池中的全部线程 */

public PoolWorker[] workers;

private ThreadPool() {

workers = new PoolWorker[5];

for (int i = 0; i < workers.length; i++) {

workers[i] = new PoolWorker(i);

}

}

private ThreadPool(int pool_worker_num) {

worker_num = pool_worker_num;

workers = new PoolWorker[worker_num];

for (int i = 0; i < workers.length; i++) {

workers[i] = new PoolWorker(i);

}

}

public staticsynchronizedThreadPool
getInstance() {

if (instance == null)

return new ThreadPool();

return instance;

}

/**

* 添加新的任务

* 每添加一个新任务。都要唤醒任务队列

* @param newTask

*/

public void addTask(Task newTask) {

synchronized (taskQueue) {

newTask.setTaskId(++taskCounter);

newTask.setSubmitTime(new Date());

taskQueue.add(newTask);

/* 唤醒队列, 開始运行 */

taskQueue.notifyAll();

}

logger.info("Submit Task<" + newTask.getTaskId() + ">: "

+ newTask.info());

}

/**

* 批量添加新任务

* @param taskes

*/

public void batchAddTask(Task[] taskes) {

if (taskes == null || taskes.length == 0) {

return;

}

synchronized (taskQueue) {

for (int i = 0; i < taskes.length; i++) {

if (taskes[i] == null) {

continue;

}

taskes[i].setTaskId(++taskCounter);

taskes[i].setSubmitTime(new Date());

taskQueue.add(taskes[i]);

}

/* 唤醒队列, 開始运行 */

taskQueue.notifyAll();

}

for (int i = 0; i < taskes.length; i++) {

if (taskes[i] == null) {

continue;

}

logger.info("Submit Task<" + taskes[i].getTaskId() + ">: "

+ taskes[i].info());

}

}

/**

* 线程池信息

* @return

*/

public String getInfo() {

StringBuffer sb = new StringBuffer();

sb.append("\nTask Queue Size:" + taskQueue.size());

for (int i = 0; i < workers.length; i++) {

sb.append("\nWorker " + i + " is "

+ ((workers[i].isWaiting()) ? "Waiting." : "Running."));

}

return sb.toString();

}

/**

* 销毁线程池

*/

public synchronized void destroy() {

for (int i = 0; i < worker_num; i++) {

workers[i].stopWorker();

workers[i] = null;

}

taskQueue.clear();

}

/**

* 池中工作线程

*

* @author obullxl

*/

private class PoolWorker extends Thread {

private int index = -1;

/* 该工作线程是否有效 */

private boolean isRunning = true;

/* 该工作线程能否够运行新任务 */

private boolean isWaiting = true;

public PoolWorker(int index) {

this.index = index;

start();

}

public void stopWorker() {

this.isRunning = false;

}

public boolean isWaiting() {

return this.isWaiting;

}

/**

* 循环运行任务

* 这或许是线程池的关键所在

*/

public void run() {

while (isRunning) {

Task r = null;

synchronized (taskQueue) {

while (taskQueue.isEmpty()) {

try {

/* 任务队列为空,则等待有新任务增加从而被唤醒 */

taskQueue.wait(20);

} catch (InterruptedException ie) {

logger.error(ie);

}

}

/* 取出任务运行 */

r = (Task) taskQueue.remove(0);

}

if (r != null) {

isWaiting = false;

try {

if (debug) {

r.setBeginExceuteTime(new Date());

taskLogger.debug("Worker<" + index

+ "> start execute Task<" + r.getTaskId() + ">");

if (r.getBeginExceuteTime().getTime()

- r.getSubmitTime().getTime() > 1000)

taskLogger.debug("longer waiting time. "

+ r.info() + ",<" + index + ">,time:"

+ (r.getFinishTime().getTime() - r

.getBeginExceuteTime().getTime()));

}

/* 该任务是否须要马上运行 */

if (r.needExecuteImmediate()) {

new Thread(r).start();

} else {

r.run();

}

if (debug) {

r.setFinishTime(new Date());

taskLogger.debug("Worker<" + index

+ "> finish task<" + r.getTaskId() + ">");

if (r.getFinishTime().getTime()

- r.getBeginExceuteTime().getTime() > 1000)

taskLogger.debug("longer execution time. "

+ r.info() + ",<" + index + ">,time:"

+ (r.getFinishTime().getTime() - r

.getBeginExceuteTime().getTime()));

}

} catch (Exception e) {

e.printStackTrace();

logger.error(e);

}

isWaiting = true;

r = null;

}

}

}

}

}

/** 任务接口类 **/

package org.ymcn.util;

import java.util.Date;

/**

* 全部任务接口

* 其它任务必须继承訪类

*

* @author obullxl

*/

public abstract class Task implements Runnable {

// private static Logger logger = Logger.getLogger(Task.class);

/* 产生时间 */

private Date generateTime = null;

/* 提交运行时间 */

private Date submitTime = null;

/* 開始运行时间 */

private Date beginExceuteTime = null;

/* 运行完毕时间 */

private Date finishTime = null;

private long taskId;

public Task() {

this.generateTime = new Date();

}

/**

* 任务运行入口

*/

public void run() {

/**

* 相关运行代码

*

* beginTransaction();

*

* 运行过程中可能产生新的任务 subtask = taskCore();

*

* commitTransaction();

*

* 添加新产生的任务 ThreadPool.getInstance().batchAddTask(taskCore());

*/

}

/**

* 全部任务的核心 所以特别的业务逻辑运行之处

*

* @throws Exception

*/

public abstract Task[] taskCore() throws Exception;

/**

* 是否用到数据库

*

* @return

*/

protected abstract boolean useDb();

/**

* 是否须要马上运行

*

* @return

*/

protected abstract boolean needExecuteImmediate();

/**

* 任务信息

*

* @return String

*/

public abstract String info();

public Date getGenerateTime() {

return generateTime;

}

public Date getBeginExceuteTime() {

return beginExceuteTime;

}

public void setBeginExceuteTime(Date beginExceuteTime) {

this.beginExceuteTime = beginExceuteTime;

}

public Date getFinishTime() {

return finishTime;

}

public void setFinishTime(Date finishTime) {

this.finishTime = finishTime;

}

public Date getSubmitTime() {

return submitTime;

}

public void setSubmitTime(Date submitTime) {

this.submitTime = submitTime;

}

public long getTaskId() {

return taskId;

}

public void setTaskId(long taskId) {

this.taskId = taskId;

}

}

转自:http://hi.baidu.com/obullxl/blog/item/ee50ad1ba8e8ff1f8718bf66.html

版权声明:本文博客原创文章。博客,未经同意,不得转载。

时间: 2024-11-05 18:27:26

线程池;java的线程池的实现原理;适用于频繁互动(如电商网站)的相关文章

从0开始 独立完成企业级Java电商网站开发

第1章 课程介绍(提供4900+问题与答案库)(提供4900+问题与答案库,你遇到的坑,别人已经出坑了)本章详细介绍Java服务端课程内容,项目演示课程安排,高大上的架构从一台服务器演变到高性能.高并发.高可用架构的过程,大型架构演进思想以及代码演进细节.(特别说明:本课程是项目实战中级课程,不会讲语法层面的内容,实战前需具备Java,SSM,Linux等基础)...1-1 课程导学1-2 课程学习与解决问题指南(最重要的一节课)1-3 大型Java项目架构演进解析 第2章 开发环境安装与配置讲

项目二:企业级java电商网站开发(服务端)

声明:项目源于网络,支持正版教程,学习使用,仅记录在此 项目介绍 企业级java电商网站开发(服务端),模块划分:用户管理,商品管理,商品品类管理,订单管理,订单详情管理,购物车管理,收货地址管理,支付管理 集成工具使用idea,一个springboot项目,使用maven进行依赖管理,持久层使用mybatis(接口+mapper xml),没有前端页面,仅服务端开发,最后返回封装好的数据,以json方式呈现,可以使用postman工具,google浏览器的Restlet Client插件等进行

java架构师、高性能、高并发、高可用、高可扩展、性能优化、集群、电商网站架构

15套java架构师.集群.高可用.高可扩展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布式项目实战视频教程 视频课程内容包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat.Spring.MongoDB.ZeroMQ.Git.Nosql.Jvm.Mecached.Netty.Nio.Mina.性能调优.高并发.to

从0开始 独立完成企业级Java电商网站开发(服务端)

原文配套视频资源获取链接:点击获取 原文配套源码资源获取链接:点击获取 第1章 课程介绍(提供5400+问题与答案库) (提供5400+问题与答案库,你遇到的坑,别人已经出坑了)本章详细介绍Java服务端课程内容,项目演示课程安排,高大上的架构从一台服务器演变到高性能.高并发.高可用架构的过程,大型架构演进思想以及代码演进细节.(特别说明:本课程是项目实战中级课程,不会讲语法层面的内容,实战前需具备Java,SSM,Linux等基础)配... 1-1 课程导学试看 1-2 课程学习与解决问题指南

Java(Android)线程池 总结

一种是使用Executors工厂生产线程池:另一种是直接使用ThreadPoolExecutor自定义. Executors工厂生产线程池 Java(Android)线程池 Trinea 介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new Thread吗? Java 1 2 3 4 5 6 7 newThread(newRunnable(){ @Ove

Java 传统线程技术

Java 多线程 在Java中,线程类Thread创建方式有两种:一是继承Thread类,重写run方法:二是,实现Runnable接口.大多数情况下,推荐使用第二种方式,实现runnable接口,这样可以很好的将任务与执行单元分离,更加突出面向对象的思想. 在JDK1.5之前,线程间互斥主依靠内置锁(监视器),而线程间通信则采用Object实例的wait,notify等方法.在JDK1.5之后,增加了很多线程新技术,如线程池.锁.信号量.条件.栅栏.阻塞队列.同步容器等. 1.       传

Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析

Java生鲜电商平台-电商中海量搜索ElasticSearch架构设计实战与源码解析 生鲜电商搜索引擎的特点 众所周知,标准的搜索引擎主要分成三个大的部分,第一步是爬虫系统,第二步是数据分析,第三步才是检索结果.首先,电商的搜索引擎并没有爬虫系统,因为所有的数据都是结构化的,一般都是微软的数据库或者 Oracle 的数据库,所以不用像百度一样用「爬虫」去不断去别的网站找内容,当然,电商其实也有自己的「爬虫」系统,一般都是抓取友商的价格,再对自己进行调整. 第二点,就是电商搜索引擎的过滤功能其实比

36套精品Java高级课,架构课,java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,第三方支付,web安全,高并发,高性能,高可用,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,大型分布式电商项目实战视频教程

新年伊始,学习要趁早,点滴记录,学习就是进步! QQ:1225462853 视频课程包含: 36套Java精品高级课架构课包含:java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,架构设计,web安全,高并发,高性能,高可用,高可扩展,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,工作流,程序调优,负载均衡,Solr集群与应用,主从复制,中间件,全文检索,Spring boot,Spring cloud,Dubbo,Elasticsearch,Redis,ActiveMQ

39套精品Java从入门到架构师|高并发|高性能|高可用|分布式|集群|电商缓存|性能调优|设计项目实战|视频教程

精品Java高级课,架构课,java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,第三方支付,web安全,高并发,高性能,高可用,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,大型分布式电商项目实战视频教程   视频课程包含: 39套Java精品高级课架构课包含:java8新特性,P2P金融项目,程序设计,功能设计,数据库设计,架构设计,web安全,高并发,高性能,高可用,高可扩展,分布式,集群,电商,缓存,性能调优,设计模式,项目实战,工作流,程序调优,负载均衡,Solr