关键技术:
- 线程组ThreadGroup可以管理多个线程,所以让线程池继承ThreadGroup。
- 无条件关闭线程池时,通过ThreadGroup的interrupt方法中断池中所有线程。
- 有条件关闭线程池时,通过ThreadGroup获得池中所有活动线程的引用,依次调用Thread的join方法等待活动线程执行完毕。当所有线程运行结束时,线程池才算被关闭。
- 将任务放在LinkedList中,由于LinkedList不支持同步,所以在添加任务和获取任务的方法声明中必须使用synchronized关键字。
/**
* 定义任务的接口类
*/
public
interface
Task {
/**
* 执行任务
*
@throws
Exception 执行过程中可能出现的异常
*/
public
void
perform()
throws
Exception;
}
/**
* 一个简单的任务
*/
public
class
MyTask
implements
Task{
/**
任务的ID
*/
private
int
taskID
=
0
;
public
MyTask(
int
id){
this
.taskID
=
id;
}
/**
* 实现Task接口的perform方法。
*/
public
void
perform()
throws
Exception{
System.out.println(
"
MyTask
"
+
taskID
+
"
: start
"
);
//
休眠一秒
try
{
Thread.sleep(
1000
);
}
catch
(InterruptedException ex) {
}
System.out.println(
"
MyTask
"
+
taskID
+
"
: end
"
);
}
}
import
java.util.LinkedList;
/**
* 线程池,继承ThreadGroup。
* ThreadGroup用于处理一组线程的类,它是一种树状结构,他的下层节点还可以是ThreadGroup对象
*/
public
class
MyThreadPool
extends
ThreadGroup {
/**
标志线程池是否开启
*/
private
boolean
isAlive;
/**
线程池中的任务队列
*/
private
LinkedList taskQueue;
/**
线程池中的线程ID
*/
private
int
threadID;
/**
线程池ID
*/
private
static
int
threadPoolID;
/**
* 创建新的线程池,numThreads是池中的线程数
*/
public
MyThreadPool(
int
numThreads) {
super
(
"
ThreadPool-
"
+
(threadPoolID
++
));
//
设置为该线程池是的daemon属性为true,
//
表示当该线程池中所有线程都被销毁时,该线程池会自动被销毁
super
.setDaemon(
true
);
this
.isAlive
=
true
;
//
新建一个任务队列
this
.taskQueue
=
new
LinkedList();
//
启动numThreads个工作线程
for
(
int
i
=
0
; i
<
numThreads; i
++
) {
new
PooledThread().start();
}
}
/**
* 添加新任务
*/
public
synchronized
void
performTask(Task task) {
if
(
!
this
.isAlive) {
//
线程被关则抛出IllegalStateException异常
throw
new
IllegalStateException();
}
if
(task
!=
null
) {
//
将任务放到任务队列的尾部
this
.taskQueue.add(task);
//
通知工作线程取任务
notify();
}
}
/**
* 获取任务
*/
protected
synchronized
Task getTask()
throws
InterruptedException {
//
如果任务列表为空,而且线程池没有被关闭,则继续等待任务
while
(
this
.taskQueue.size()
==
0
) {
if
(
!
this
.isAlive) {
return
null
;
}
wait();
}
//
取任务列表的第一个任务
return
(Task)
this
.taskQueue.removeFirst();
}
/**
* 关闭线程池,所有线程停止,不再执行任务
*/
public
synchronized
void
close() {
if
(isAlive) {
this
.isAlive
=
false
;
//
清除任务
this
.taskQueue.clear();
//
中止线程池中所有线程
this
.interrupt();
}
}
/**
* 关闭线程池,并等待线程池中的所有任务被运行完。
* 但是不能接受新的任务。
*/
public
void
join() {
//
通知其他等待线程“该线程池已关闭”的消息
synchronized
(
this
) {
isAlive
=
false
;
notifyAll();
}
//
等待所有线程完成
//
首先建立一个新的线程数组。activeCount方法获取线程池中活动线程的估计数
Thread[] threads
=
new
Thread[
this
.activeCount()];
//
将线程池中的活动线程拷贝到新创建的线程数组threads中。
int
count
=
this
.enumerate(threads);
for
(
int
i
=
0
; i
<
count; i
++
) {
try
{
//
等待线程运行结束
threads[i].join();
}
catch
(InterruptedException ex) {
}
}
}
/**
* 内部类,用于执行任务的工作线程
*/
private
class
PooledThread
extends
Thread {
//
构造方法
public
PooledThread() {
//
第一个参数为该线程所在的线程组对象,即当前线程池对象
//
第二个参数为线程名字
super
(MyThreadPool.
this
,
"
PooledThread-
"
+
(threadID
++
));
}
public
void
run() {
//
如果该线程没有被中止
while
(
!
isInterrupted()) {
//
获取任务
Task task
=
null
;
try
{
task
=
getTask();
}
catch
(InterruptedException ex) {
}
//
只要线程池的任务列表不为空,getTask方法总能得到一个任务。
//
若getTask()返回null,则表示线程池中已经没有任务,而且线程池已被关闭。
if
(task
==
null
) {
return
;
}
//
运行任务,吸收异常
try
{
task.perform();
}
catch
(Throwable t) {
//
当线程组中的线程有未被捕获的异常发生时,JVM就会去调用uncaughtException方法。
uncaughtException(
this
, t);
}
}
}
}
}
package
book.thread.pool;
/**
* 测试线程池
*/
public
class
PoolTest {
public
static
void
main(String[] args) {
//
线程池中的线程数
int
numThreads
=
3
;
//
生成线程池
MyThreadPool threadPool
=
new
MyThreadPool(numThreads);
//
任务数
int
numTasks
=
10
;
//
运行任务
for
(
int
i
=
0
; i
<
numTasks; i
++
) {
threadPool.performTask(
new
MyTask(i));
}
//
关闭线程池并等待所有任务完成
threadPool.join();
}
}
分享到:
相关推荐
Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...
Java多线程读大文件 java多线程写文件:多线程往队列中写入数据
java多线程进度条
java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题
在本文中,我们将深入浅出Java多线程编程的世界,探索多线程编程的基本概念、多线程编程的优点、多线程编程的缺点、多线程编程的应用场景、多线程编程的实现方法等内容。 一、多线程编程的基本概念 多线程编程是指...
一个java 多线程操作数据库应用程序!!!
java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例
Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...
该文档总结了Java多线程相关的知识点,分享给大家,简单易懂!
详细的讲解了java多线程的原理,并配有代码进行实战,适合java初学者和想对多线程有进一步了解的人。
一张图方便理解和掌握java 多线程之间通信的实质 java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,...
java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。
java多线程,对多线程,线程池进行封装,方便使用
现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。...本文档提供Java多线程编程经验,方便广大Java爱好者研究学习Java多线程
java多线程处理大数据,可根据配置的线程数,任务去调度处理
java多线程并发的在新窗口
Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...
资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...
java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制
java多线程并发查询数据库,使用线程池控制分页,并发查询。