线程池的作用:
线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。
为什么要用线程池:
- 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务
- 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)
import java.util.LinkedList;
public class ThreadPool extends ThreadGroup{
private boolean isClosed = false; //线程池是否关闭
private LinkedList<Runnable> workQueue; //工作队列
private static int threadPoolID = 1; //线程池的id
public ThreadPool(int poolSize){ //poolSize 表示线程池中的工作线程的数量
super(threadPoolID+""); //指定ThreadGroup的名称
setDaemon(true); //继承到的方法,设置是否守护线程池
workQueue = new LinkedList<Runnable>(); //创建工作队列
for(int i=0;i< poolSize; i++){
new WorkThread(i).start(); //创建并启动工作线程,线程池数量是多少就创建多少个工作线程
}
}
public synchronized void execute(Runnable task){
if(isClosed){
throw new IllegalStateException();
}
if(task != null){
workQueue.add(task); //向队列中加入一个任务
notify(); //唤醒一个正在getTask()方法中待任务的工作线程
}
}
private synchronized Runnable getTask(int threadid) throws InterruptedException{
while(workQueue.size()==0){
if(isClosed)
return null;
System.out.println("工作线程"+ threadid + "等待任务...");
wait();
}
System.out.println("工作线程"+ threadid + "开始执行任务...");
return (Runnable) workQueue.removeFirst(); //返回队列中第一个元素,并从队列中删除
}
public synchronized void closePool(){
if(! isClosed){
waitFinish(); //等待工作线程执行完毕
isClosed = true;
workQueue.clear(); //清空工作队列
interrupt(); //中断线程池中的所有工作线程,此方法继承自ThreadGroup类
}
}
public void waitFinish(){
synchronized(this){
isClosed =true;
notifyAll(); //唤醒所有还在getTask()方法中等待任务的工作线程
}
Thread[] threads = new Thread[activeCount()]; //activeCount() 返回该线程组中活动线程的估计值。
int count = enumerate(threads); //enumerate()方法继承自ThreadGroup类,根据活动线程的估计值获得线程组中当前所有活动的工作线程
for(int i=0; i< count; i++){
try{
threads[i].join(); //等待工作线程结束
} catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
private class WorkThread extends Thread{
private int id;
public WorkThread(int id){
//父类构造方法,将线程加入到当前的ThreadPool线程组中
super(ThreadPool.this, id+"");
this.id=id;
}
public void run(){
while(! isInterrupted()){ //isInterrupted() 方法继承自Thread类,判断线程是否被中断
Runnable task = null;
try{
task = getTask(id); //取出任务
}catch(InterruptedException ex){
ex.printStackTrace();
}
//如果getTask()返回Null或者线程执行getTask()时被中断,则结束此线程
if(task == null)
return;
try{
task.run(); //运行任务
} catch(Throwable t){
t.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException{
ThreadPool threadPool = new ThreadPool(3); //创建一个有3个工作线程的线程池
Thread.sleep(500); //休眠500毫秒,以便让线程池中的工作线程全部运行
//运行任务
for(int i=0; i<=5; i++){ //创建6个任务
threadPool.execute(createTask(i));
}
System.out.println("......................................");
threadPool.waitFinish(); //等待所有任务执行完毕
threadPool.closePool(); //关闭线程池
System.out.println("game over!");
}
private static Runnable createTask(final int taskID){
return new Runnable(){
public void run(){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(taskID + ": Hello");
}
};
}
}
相关推荐
Java代码中展示的`ThreadPool`类是作者实现的一个简单线程池示例,使用了`LinkedList`作为工作队列,`ThreadPool`类继承了`ThreadGroup`,这在JDK 1.4版本中是一种常见实现方式。但在JDK 1.5及以上版本,推荐使用`...
2. **附录B:ThreadGroup API**(The ThreadGroup API) - **API介绍**:介绍`ThreadGroup`类API的基本信息。 - **功能特性**:总结`ThreadGroup`类的主要功能和特点。 - **使用场景**:列举`ThreadGroup`类在多...
- **实现Runnable接口**:Java提供了两种方式来创建线程,一种是继承Thread类,另一种是实现Runnable接口。如果选择实现Runnable接口,那么你的类可以同时继承其他类,因为Java不支持多重继承。实现Runnable接口后...
- Thread类的构造器包括:Thread(Runnable target)、Thread(Runnable target, String name)、Thread(ThreadGroup group, Runnable target)、Thread(ThreadGroup group, Runnable target, String name)、Thread...
- `threadFactory(ThreadGroup group, ThreadFactory threadFactory)`:创建一个定制的线程工厂,可以自定义线程组和线程工厂。 4. **Callable任务的转换** - `callable(Runnable task)`:将Runnable转换为...
- **ThreadGroup的使用**:`Server`类中定义了一个`ThreadGroup`实例,名为`threadGroup`,用于统一管理所有客户端连接处理线程。这是实现高效并发处理的关键,确保了线程资源的合理分配与管理。 - **线程生命周期...
- `Thread(ThreadGroup group, Runnable target, String name, long stackSize)` **3. 启动线程** 启动线程是通过调用`Thread`对象的`start()`方法完成的。调用`start()`方法会创建一个新的执行线程,并使该线程...
线程组(ThreadGroup)是用来管理一组线程的容器,它自身也是线程。线程组可以包含子线程组,形成一个树形结构。线程组提供了线程的统计、监控和保护等功能,例如,可以一次性停止组内所有线程。 在实际编程中,...
- 可以通过`ThreadGroup`类创建和管理线程组。 #### 十、线程池 - **线程池**: - 是一种管理线程的有效方式,可以复用线程,减少创建和销毁线程的开销。 - 常见的线程池包括`ExecutorService`接口和其实现类如...
Java中线程的创建主要有两种方式,一种是继承Thread类,另一种是实现Runnable接口。在上述内容中,定义了一个继承自Thread类的MyThread类,并在构造函数中传递了编号作为线程的标识。通过覆写Thread类的run()方法来...
- **继承Thread类**:创建新的Thread类并重写run()方法。 - **实现Runnable接口**:创建类实现Runnable接口,重写run()方法,然后在Thread构造函数中传入实现Runnable的实例。 - **使用Callable和FutureTask**:...
- **继承与多态**:理解单一继承和接口实现,以及多态的概念。 - **访问修饰符**:掌握public、private、protected、internal的用法。 - **抽象类与接口**:区别抽象类与接口,何时使用它们。 - **构造函数**:...
- `Executor` 和 `ExecutorService`:用于管理和控制线程池。 - `ThreadFactory`:用于创建新的线程。 - `CountDownLatch`、`CyclicBarrier` 和 `Semaphore`:用于协调多个线程间的同步。 #### 3. 抽象类和接口的...
- 创建线程的方式:继承`Thread`类与实现`Runnable`接口。 - `Callable`与`Future`的使用。 - 线程同步机制:`synchronized`关键字、`ReentrantLock`等。 - 线程池的创建与管理。 - **面试考察要点:** - 死锁...
最后,`java.lang.ThreadGroup`类是线程的容器,可以用来组织和管理线程。它可以用于设置线程的优先级、检查线程状态,甚至杀死线程。 总结起来,Java线程源码的学习涵盖了线程的创建、管理、同步和通信等多个方面...
- **Thread和Service的区别**:Thread是执行任务的线程,而Service是Android四大组件之一。 - **线程同步和安全**:使用synchronized关键字或Lock对象保证线程安全。 - **IntentService和Service的区别**:...
这个配置文件定义了Scheduler的实例名称,是否启用RMI,线程池的类、线程数量、优先级以及线程是否继承初始化线程的类加载器。 总之,Quartz为Java开发者提供了一套强大的工具,可以方便地创建、管理和执行定时任务...
4. 学习线程池的使用,如ExecutorService和ThreadPoolExecutor,以及线程池的参数配置。 五、I/O与NIO 1. 分析Java传统I/O(-blocking I/O)与非阻塞I/O(New IO, NIO)的区别。 2. 掌握FileInputStream、...
通过实现Runnable接口或继承Thread类,你可以创建并管理自己的线程。并发编程时,理解锁(synchronized关键字)、条件变量(wait()和notify()方法)以及线程池(ExecutorService)的概念是必要的。 对于网络编程,...