java线程池实例下载_Java线程池的实现示例

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,下面我们来看Java线程池的实现示例,具体如下。

最近在写Java程序的时候,接触到一些多线程方面的东西,用到了Java中的线程池。JDK中对线程池的支持比较完善,在java.util.concurrent包中,用ThreadPoolExecuter类表示一个线程池,同时还有一个Executor类扮演着线程池工厂的角色。例如:

 代码如下复制代码
public static ExecutorService newFixedThreadPool(int nThreads)

public static ExecutorService newSingleThreadExecutor()

public static ExecutorService newCachedThreadPool()

...

这些工厂方法,从本质上,都是调用了ThreadPoolExecutor类的构造函数:

 代码如下复制代码
public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler)

参数含义如下:

corePoolSize:线程池中应该保持的线程数量,即使线程空闲

maximumPoolSize:线程池中最大线程的数量

keepAliveTime:当线程数量大于corePoolSize时,指定空闲线程存在多久会被销毁

unit:keepAliveTime的单位

workQueue:任务队列,被提交但还没有执行

threadFactory:线程工厂

handler:拒绝策略

实现思路

从ThreadPoolExecutor的构造函数中,我们大概知道实现一个线程池需要哪些东西,如果完全按照构造函数中的参数来的话,太麻烦,有太多地方需要考虑,因此实现一个简单版的。

首先需要考虑线程池中存放多少线程。可以简单用一个变量来指定,并且这些线程要放在一个容器里,便于销毁,也便于知道他们的状态。

然后我们要考虑一个作为任务队列的容器。假如线程池中有5个线程,如果5个线程都处于工作状态的话,这时候送来的任务就需要放在任务队列中等待。

最后是线程池中工作线程的形式。工作线程在创建时开始就应该启动,其所做的工作主要是:从任务队列中取出任务-执行任务这样的无限循环。

工作线程的一种实现方式:

 代码如下复制代码

class WorkerThread extends Thread {

private Boolean isRunning = true;

public void close() {

isRunning = false;

}

public void run() {

while (isRunning) {

Runnable task = null;

try {

task = taskQueue.take();

} catch (InterruptedException e) {

e.printStackTrace();

}

task.run();

}

}

}

WorkerThread是线程池的内部类,其中,taskQueue是任务队列,这里采用了BlockingQueue接口的一种实现,其put和take方法都是阻塞的。提交任务和销毁线程池如下:

 代码如下复制代码

public void submit(Runnable task) {

if (currentWorking() < limits) {

WorkerThread worker = new WorkerThread();

worker.start();

workers.add(worker);

}

try {

taskQueue.put(task);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

public void destroy() {

while (!taskQueue.isEmpty());

for (WorkerThread worker : workers) {

worker.close();

}

}

完整代码在这里。

 代码如下复制代码

import java.util.ArrayList;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

/**

* Created by rahul on 7/20/16.

*/

public class SimpleThreadPool {

public static BlockingQueue testQueue = new LinkedBlockingQueue<>();

private int limits;

private ArrayList workers;

private BlockingQueue taskQueue;

SimpleThreadPool(int nums) {

limits = nums;

workers = new ArrayList<>();

taskQueue = new LinkedBlockingQueue<>();

}

private int currentWorking() {

return workers.size();

}

public void submit(Runnable task) {

if (currentWorking() < limits) {

WorkerThread worker = new WorkerThread();

worker.start();

workers.add(worker);

}

try {

taskQueue.put(task);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

public void destroy() {

while (!taskQueue.isEmpty());

for (WorkerThread worker : workers) {

worker.close();

}

}

class WorkerThread extends Thread {

private Boolean isRunning = true;

public void close() {

isRunning = false;

}

public void run() {

while (isRunning) {

Runnable task = null;

try {

task = taskQueue.take();

} catch (InterruptedException e) {

e.printStackTrace();

}

task.run();

}

}

}

public static void main(String[] args) {

SimpleThreadPool pool = new SimpleThreadPool(10);

for (int i = 0; i < 100; i) {

pool.submit(new test("Task " i));

}

pool.destroy();

}

}

class test implements Runnable {

private String id;

public test(String str) { id = str; }

public void run() {

try {

System.out.println("Start process " id);

Thread.sleep(1000);

System.out.println(id " Completed!");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

线程池看似简单,其实很复杂,因为如果真要到一个应用级别的话,要考虑的东西还有很多,例如何时该启动一个线程,何时线程应该中止与挂起,任务队列的阻塞与超时,任务拒绝策略,线程生命周期等。至于本文实现的线程池

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值