java线程池如何实现_java线程池怎么实现的

展开全部

线程池简介:

多线程技术主要解决处理器单元内多个线程执行的问e69da5e887aa62616964757a686964616f31333365633864题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。

假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。

如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。

一个线程池包括以下四个基本组成部分:

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

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

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

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

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

线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目,看一个例子:

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

代码实现中并没有实现任务接口,而是把Runnable对象加入到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了package mine.util.thread;

import java.util.LinkedList;

import java.util.List;

/**

* 线程池类,线程管理器:创建线程,执行任务,销毁线程,获取线程基本信息

*/

public final class ThreadPool {

// 线程池中默认线程的个数为5

private static int worker_num = 5;

// 工作线程

private WorkThread[] workThrads;

// 未处理的任务

private static volatile int finished_task = 0;

// 任务队列,作为一个缓冲,List线程不安全

private List taskQueue = new LinkedList();

private static ThreadPool threadPool;

// 创建具有默认线程个数的线程池

private ThreadPool() {

this(5);

}

// 创建线程池,worker_num为线程池中工作线程的个数

private ThreadPool(int worker_num) {

ThreadPool.worker_num = worker_num;

workThrads = new WorkThread[worker_num];

for (int i = 0; i 

workThrads[i] = new WorkThread();

workThrads[i].start();// 开启线程池中的线程

}

}

// 单态模式,获得一个默认线程个数的线程池

public static ThreadPool getThreadPool() {

return getThreadPool(ThreadPool.worker_num);

}

// 单态模式,获得一个指定线程个数的线程池,worker_num(>0)为线程池中工作线程的个数

// worker_num<=0创建默认的工作线程个数

public static ThreadPool getThreadPool(int worker_num1) {

if (worker_num1 <= 0)

worker_num1 = ThreadPool.worker_num;

if (threadPool == null)

threadPool = new ThreadPool(worker_num1);

return threadPool;

}

// 执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

public void execute(Runnable task) {

synchronized (taskQueue) {

taskQueue.add(task);

taskQueue.notify();

}

}

// 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

public void execute(Runnable[] task) {

synchronized (taskQueue) {

for (Runnable t : task)

taskQueue.add(t);

taskQueue.notify();

}

}

// 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

public void execute(List task) {

synchronized (taskQueue) {

for (Runnable t : task)

taskQueue.add(t);

taskQueue.notify();

}

}

// 销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁

public void destroy() {

while (!taskQueue.isEmpty()) {// 如果还有任务没执行完成,就先睡会吧

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

// 工作线程停止工作,且置为null

for (int i = 0; i 

workThrads[i].stopWorker();

workThrads[i] = null;

}

threadPool=null;

taskQueue.clear();// 清空任务队列

}

// 返回工作线程的个数

public int getWorkThreadNumber() {

return worker_num;

}

// 返回已完成任务的个数,这里的已完成是只出了任务队列的任务个数,可能该任务并没有实际执行完成

public int getFinishedTasknumber() {

return finished_task;

}

// 返回任务队列的长度,即还没处理的任务个数

public int getWaitTasknumber() {

return taskQueue.size();

}

// 覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数

@Override

public String toString() {

return "WorkThread number:" + worker_num + "  finished task number:"

+ finished_task + "  wait task number:" + getWaitTasknumber();

}

/**

* 内部类,工作线程

*/

private class WorkThread extends Thread {

// 该工作线程是否有效,用于结束该工作线程

private boolean isRunning = true;

/*

* 关键所在啊,如果任务队列不空,则取出任务执行,若任务队列空,则等待

*/

@Override

public void run() {

Runnable r = null;

while (isRunning) {// 注意,若线程无效则自然结束run方法,该线程就没用了

synchronized (taskQueue) {

while (isRunning && taskQueue.isEmpty()) {// 队列为空

try {

taskQueue.wait(20);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

if (!taskQueue.isEmpty())

r = taskQueue.remove(0);// 取出任务

}

if (r != null) {

r.run();// 执行任务

}

finished_task++;

r = null;

}

}

// 停止工作,让该线程自然执行完run方法,自然结束

public void stopWorker() {

isRunning = false;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java线程池可以很好地管理和调度多线程任务,实现异步任务。以下是一个简单的示例,演示如何使用Java线程池实现异步任务: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class AsyncTasks { private ExecutorService executorService = Executors.newFixedThreadPool(10); public void runAsyncTask(Runnable task) { executorService.execute(task); } } ``` 在上面的代码中,我们创建了一个名为`AsyncTasks`的类,该类具有一个`ExecutorService`对象,用于管理我们的线程池。我们还定义了一个`runAsyncTask`方法,该方法接受一个`Runnable`对象作为参数,并将其提交给线程池进行异步执行。 要使用这个类,我们可以创建一个新的异步任务并将其传递给`runAsyncTask`方法。例如: ```java public class Main { public static void main(String[] args) { AsyncTasks asyncTasks = new AsyncTasks(); // 创建一个新的异步任务 Runnable task = new Runnable() { @Override public void run() { // 执行异步任务 System.out.println("Async task is running."); } }; // 提交异步任务到线程池 asyncTasks.runAsyncTask(task); } } ``` 在这个例子中,我们首先创建了一个`AsyncTasks`对象,然后创建了一个新的`Runnable`对象,该对象包含了我们想要在异步任务中执行的代码。最后,我们将这个`Runnable`对象传递给`runAsyncTask`方法,该方法将任务提交给线程池进行异步执行。 使用Java线程池实现异步任务可以提高程序的并发性和响应性,并且可以有效地管理和调度多线程任务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值