`
daweiyuan
  • 浏览: 20343 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

J2Me线程池

阅读更多
鉴于手机平台的特殊性,而且项目中多处用到线程,为便于线程管理,节约资源,提高运行速度,创建了线程池,对线程统一进行管理。
用到的原则:
   当调用线程池的addTask(TaskThread task,String name)时,如果此时线程池中的线程有空闲的,从freeQueue中调用一个空闲的线程进行处理;如果线程池中没有空闲线程,且线程总量没达到最大,则批量创建新的线程,将其加到freeQueue中,然后从中取用一个执行任务;如果此时线程池中的线程已达到最大容量,且缓冲队列blockingQueue未满,将其加到缓冲队列中,等待执行。如果缓冲队列blockingQueue已满,抛出异常。此处应该采取异常处理机制,尚未处理。
以下是线程池类的主要代码:
/**
* @建立简单的线程池,实现线程的初步管理
* @2009.11.22.14.37
*/
public class ThreadPool
{
private String classname = this.getClass().getName();
// 优先级低 
public static final int PRIORITY_LOW = 0; 
  
     // 普通 
public static final int PRIORITY_NORMAL = 1; 
  
     // 高 
public static final int PRIORITY_HIGH = 2; 
/**
* 线程池中最少的线程数
*/
private static final int corePoolSize = 3;
/**
* 线程池中线程的最大数目
*/
private static final int produceTaskMaxNum = 15;
private static final int increment = 3;
/**
* 线程池所使用的缓冲队列
*/
private Stack blockingQueue;
/**
* 线程池所使用的空闲队列
*/
private Stack freeQueue;
/**
* 线程池所使用的工作队列
*/
private Hashtable workQueue;

/**
* 线程池所中目前所有的线程
*/
private Hashtable allQueue;
/**
* 缓冲队列的容量
*/
private static final int tasknum = 15;

private static ThreadPool instance = null;
private int _threadCount = 0; 
private  ThreadPool()
{
blockingQueue = new Stack();
freeQueue = new Stack();
workQueue = new Hashtable();
allQueue = new Hashtable();
//先创建最小线程数的线程
for (int i = 0; i < corePoolSize; i++) {
TaskThread t = new TaskThread();
t.set_pool(this);
freeQueue.push(t);
allQueue.put(t.getName(),t);
_threadCount++;
}
}

/**
* @return
* 得到线程池的实例
*/
public  synchronized static ThreadPool getInstance()
{
if(instance == null)
{
instance = new ThreadPool();
}
return instance;
}




/**
* @param task 要执行的任务
* @param name 任务的名字
*     添加并执行新的任务
*/
public void addTask(Runnable task,String name)
{
if (!freeQueue.empty())
{
TaskThread tt= (TaskThread) freeQueue.pop();
System.out.println("*****"+classname+"tt:tt.getKey():"+tt.getKey()+"****"+tt.getName()+"******"+tt.getTarget());
freeQueue.push(tt);
}
System.out.println("***添加执行新的任务:"+name);
int len = _threadCount;
System.out.println("***目前的线程数:"+len);
boolean isStart = false;
TaskThread t = null;
//如果线程没有到达最大值
if (len<produceTaskMaxNum)
{
//如果空闲列表非空
if (freeQueue.size()>0)
{
System.out.println("***线程空闲队列中有闲置线程");
//从空闲队列pop一个线程
t = (TaskThread) freeQueue.pop();
t.setKey(name);
t.setTarget(task);
t.set_pool(this);
if (t.get_shutdown()) {
isStart = true;
//打开开关
System.out.println("*********是已回收线程,打开开关****************");
synchronized (t) {
t.open();
}
}
//加入工作字典
workQueue.put(t.key,t);
if (!isStart) {
System.out.println("***第一次,要start()");
t.start();
}
}
else
{
//无空闲线程,创建新的线程
incrementThread(task,name);
}
}
else
{
//如果线程达到max就把任务加入等待队列
if (blockingQueue.size()<tasknum) {
t= new TaskThread();
t.setKey(name);
t.setTarget(task);
t.set_pool(this);
blockingQueue.push(task);
}
else
{
try {
throw new Exception("******缓冲队列已满,线程池已达到极限!");
} catch (Exception e) {
e.printStackTrace();
}

}

}
}

/**
* @param task
* @param name
* 当空闲线程用完时,调用此函数,创建新的线程。
*/
public void incrementThread(Runnable task,String name)
{
TaskThread t = null;
int len = getThreadsCount();
//如果没有空闲队列了,就根据增量创建线程
for (int i = 0; i < increment; i++) {
//判断线程的总量不能超过max
if ((len+i)<produceTaskMaxNum) {
t = new TaskThread();
t.set_pool(this);
_threadCount++;
//加入线程字典
allQueue.put(t.getName(),t);
freeQueue.push(t);
}
else
{
try
{//采取异常处理策略。未处理**
throw new Exception("*******线程数量已达到最大!");
}
catch (Exception e)
{
e.printStackTrace();
}
break;
}
}
//从空闲队列提出出来设置后开始执行
t = (TaskThread) freeQueue.pop();
//填充任务线程
t.setTarget(task);
t.setKey(name);
//加入工作字典
workQueue.put(t.key,t);
t.start();
}

/**
* @param task
* 线程执行完毕触发的事件
*/
public void complete(TaskThread task)
{
System.out.println("***开始回收线程"+task.getName());
if (workQueue.containsKey(task.key)) {
//首先因为工作执行完了,所以从正在工作字典里删除
workQueue.remove(task.key);
}
else {
System.out.println("***没有将task.key加入");
}
task.shutDown();
//从等待任务队列提取一个任务
if (blockingQueue.size()>0) {
System.out.println("***从缓冲队列中取任务执行");
TaskThread t = (TaskThread) blockingQueue.pop();
TaskThread nt = null;
//如果有空闲的线程,就是用空闲的线程来处理
if (freeQueue.size()>0) {
System.out.println("***从空闲队列中取线程");
nt = (TaskThread) freeQueue.pop();
nt.setKey(t.getKey());
nt.setTarget(t.getTarget());
//添加到工作字典中
workQueue.put(nt.key,nt);
if (!nt.get_shutdown()) {
//线程尚未运行过,许调用start()启动。
nt.start();
}
else
{
synchronized (nt)
{//线程已经运行过,再次运行,不需调用start()方法
nt.open();
}
}
}
else
{
//无空闲线程,创建新的线程
incrementThread(task.getTarget(),task.getName());
}
}
else
{
//如果没有等待执行的操作就回收多余的工作线程
if (freeQueue.size()>corePoolSize-1) {
//当空闲线程超过最小线程数就回收多余的
//线程自然执行完毕,出入死亡状态
allQueue.remove(task.getName());
task.shutDown();
_threadCount--;
System.out.println("***空闲线程池已满,线程"+task.getName()+"销毁"+"目前的线程数:"+_threadCount);

}
else
{
try
{//让该线程处于等待状态,不让其死去
//如果没超过就把线程从工作字典放入空闲队
System.out.println("***把线程"+task.getName()+"放入空闲队");
freeQueue.push(task);
System.out.println("***调用"+task+".wait()让线程"+task.getName()+"处于等待状态freeQueue.size():"+freeQueue.size());
System.out.println("回收线程"+task.getName()+"结束");
task.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}

public int getThreadsCount()
{
return this._threadCount;
}

public Hashtable getWorkQueue() {
return workQueue;
}

public void setWorkQueue(Hashtable workQueue) {
this.workQueue = workQueue;
}

}

任务执行类:TaskThread
package com.pojaa.util;

/**
* @author yuandawei
*     @类描述:执行线程池传来的任务
*/
public class TaskThread extends Thread{

private TaskThread instance;
/**
* 标志该线程
*/
String key = null;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}

/**
* 线程池
*/
private ThreadPool _pool;
public ThreadPool get_pool() {
return _pool;
}
public void set_pool(ThreadPool _pool) {
this._pool = _pool;
}

/**
* 需要执行的目标对象
*/
private Runnable _target;
/**
* 开关
*/
private boolean _shutdown = false;
public boolean get_shutdown() {
return _shutdown;
}
public void set_shutdown(boolean _shutdown) {
this._shutdown = _shutdown;
}

private boolean _idle = false;
public TaskThread(){
instance = this;
//super();
}
/**
* @param target
*/
public TaskThread(Runnable target)
{
super(target);
}

public TaskThread(Runnable target,String name)
{
super(target,name);
}

public TaskThread(Runnable target, String name, ThreadPool pool)
{
super(name);
this._pool = pool;
this._target = target;
}

public TaskThread(String name)
{
super(name);
this.key = name;
}

public Runnable getTarget()
{
return this._target;
}
public boolean isIdle()
{
return this._idle;
}

public synchronized void shutDown() {
this._shutdown = true;
notifyAll();
}

public synchronized void setTarget(Runnable target) {
this._target = target;
//notifyAll();
}

public  void run()
{
System.out.println("***是否执行 标记:"+_shutdown);
while (!this._shutdown) {
this._idle = false;
if (this._target != null) {
System.out.println("****任务开始执行"+this.getClass().getName()+this.getKey());
this._target.run();
System.out.println("****任务结束执行"+this.getClass().getName()+this.getKey());
}
this._idle = true;
synchronized (this)
{
if (this.get_pool()!= null) {
System.out.println(this+"._pool.complete(this)开始"+this.getClass().getName()+this.getKey());
this._pool.complete(this);
System.out.println(this+"._pool.complete(this)结束"+this.getClass().getName()+this.getKey());
this._idle = false;
}
else {
System.out.println("**********this.getKey()"+this.getKey()+"*******"+"this.get_pool()"+this.get_pool());
}
}
}
}

public void open()
{
this._shutdown = false;
notifyAll();
}

}
分享到:
评论
2 楼 鸟哥哥 2009-12-23  
移植时你就知道什么了。
1 楼 linkerlin 2009-12-21  
手机这样用不合适。
本来资源就很少了。
还是不要用啥池子了。

相关推荐

    线程池技术在J2ME网络通信中的应用研究

    ### 线程池技术在J2ME网络通信中的应用研究 #### 引言与背景 随着嵌入式设备及移动通信技术的迅速发展,尤其是智能手机和平板电脑的普及,移动设备的应用范围日益广泛,从基本的通讯工具演变为集信息获取、娱乐等...

    线程池技术在J2ME网络通信中的应用研究.

    ### 线程池技术在J2ME网络通信中的应用研究 #### 一、引言 随着嵌入式设备的迅速发展,特别是智能手机和平板电脑等手持移动设备的普及,移动应用开发的需求日益增长。Java作为一种重要的编程语言,在移动设备应用...

    J2ME的多线程教程和测试

    虽然J2ME的标准库没有提供线程池功能,但开发者可以自行实现简单的线程池管理,通过复用已创建的线程来减少资源消耗。 五、线程生命周期 线程经历新建、就绪、运行、阻塞和终止等状态。当调用`start()`方法,线程...

    J2ME应用程序性能优化的探讨

    - **资源池技术**:合理利用资源池技术,如线程池、连接池等,可以显著降低资源的创建和销毁成本。 - **异步处理**:对于耗时的操作采用异步处理的方式,避免阻塞主线程,提高程序的响应速度。 3. **数据压缩和...

    J2ME手机聊天室例子

    为了提高效率和可靠性,服务器端可能还需要实现线程池管理和数据缓存机制。 消息的序列化和反序列化也是必要的。J2ME可能不支持复杂的对象序列化,所以我们可能需要自定义简单的数据格式,如XML或JSON,来传递聊天...

    9. 多线程1.rar

    可以通过设置优先级或者使用线程池来管理线程,比如`ThreadPoolExecutor`在J2EE中可以实现线程的复用,但在J2ME中可能需要手动实现类似功能。 文件`09-1.swf`, `09-2.swf`, `09-3.swf`可能是教程的多媒体部分,它们...

    java线程.rar

    Java的ExecutorService接口和ThreadPoolExecutor类提供了线程池管理的功能,但J2ME可能不完全支持这些高级特性,开发者需要根据具体平台特性选择合适的方法。 线程优先级也是Java线程的一个特性,可以使用set...

    JAVA实验报告

    - **J2ME (Java 2 Micro Edition)**:专为移动设备和嵌入式设备设计的轻量级版本。 Java语言的主要特点包括但不限于: - **面向对象**:支持封装、继承、多态等面向对象编程的核心概念。 - **跨平台**:Java程序...

    JAVA程序员之路书

    2. **多线程**:Java的并发模型是高级应用的基础,掌握线程同步、死锁避免、线程池使用等概念至关重要。 3. **异常处理**:Java的异常处理机制是程序健壮性的保障,学会正确使用try-catch-finally结构,理解checked...

    非常有用的java尝试

    5. **多线程**:Java中的线程创建(Thread类、Runnable接口)、同步机制(synchronized关键字、wait()、notify()方法)以及线程池的使用。 6. **网络编程**:Socket编程,如何创建客户端和服务端进行数据通信。 7....

    Java各公司面试题

    3. 线程池:理解ExecutorService、ThreadPoolExecutor等线程池组件,以及如何优化线程池配置。 六、IO流 1. 流的分类:理解字节流和字符流的区别,以及输入流、输出流、节点流和处理流的概念。 2. NIO:了解非阻塞I...

    高效MIDP编程

    4. **线程池**:使用线程池可以减少创建和销毁线程的成本。对于需要频繁执行的任务,可以创建一个线程池来管理这些任务。 通过以上策略的应用,开发者可以显著提升MIDP应用的执行速度,为用户提供更加流畅的体验。

    java 从入门到精通.zip

    7.3 线程池:了解ExecutorService,使用ThreadPoolExecutor创建线程池,优化多线程执行。 八、网络编程 8.1 网络编程基础:理解TCP和UDP协议,掌握Socket和ServerSocket的使用。 8.2 HTTP通信:实现简单的HTTP...

    Java面试宝典1,找工作的好帮手

    通过使用 `java.util.concurrent.ExecutorService` 接口和其实现类 `ThreadPoolExecutor`,可以创建自定义的线程池。 #### 三、数据库操作 1. **SQL 语句执行:** - **问题**:`Statement` 和 `PreparedStatement...

    java方向毕业设计题目.pdf

    3. **多线程编程**:深入理解线程同步、并发控制(如synchronized关键字、volatile变量、Lock接口)以及线程池的使用。 4. **网络通信**:TCP/IP协议栈、Socket编程,如何在Java中实现客户端和服务器间的通信。 5....

    JAVA2211.rar

    【描述】虽然描述为空,但通常此类文件会包含一系列关于Java 2(J2SE、J2EE或J2ME)或更高版本的学习资源,可能是针对初学者到进阶者的教学材料,或者是某个特定主题,如多线程、集合框架、IO流、网络编程、设计模式...

    中国科学技术大学J2EE课件

    1. **3_1 J2EEOverview.ppt**:这部分内容通常会介绍J2EE的基本概念,包括J2EE平台的架构、版本历史、主要组件以及其与J2SE和J2ME的关系。它可能还会讲解J2EE如何提供Web、EJB(Enterprise JavaBeans)、JMS(Java ...

    Java2实用教程代码(第三版例子代码)

    Java2平台分为标准版(J2SE)、企业版(J2EE)和微型版(J2ME),分别面向桌面应用、服务器端应用和嵌入式设备。 在《Java2实用教程》中,读者将学习到以下关键知识点: 1. **基础语法**:包括数据类型(如整型、...

Global site tag (gtag.js) - Google Analytics