Android中的线程池与任务队列

Android中的线程池与任务队列:

            在Android手机开发的时候,考虑的资源问题是必须的。当然我们要注重线程的消耗资源的过程,线程在new的时候最消耗内存开销,而在运行的时候远远小于new的时候的内存开销。故我们可以考虑应用线程池与任务队列去解决线程的消耗问题。

实例讲解:
    我们在最初加载的时候,可以new一个线程类,单独线程需要之行的操作。代码如下:
         1.  DownloadTask.java:
package com.threadExecutorService.test;

public class DownloadTask implements Runnable{
	public String name;
	public DownloadTask(String name){
		this.name=name;
	}
	@Override
	public void run() {
//		String name=Thread.currentThread().getName();
		try {
			Thread.sleep(1500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(name + " executed OK!");
	}
	public String getFileId(){
		return name;
	}

}


2.  线程管理类  DownloadTaskManager.java
package com.threadExecutorService.test;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

public class DownloadTaskManager {
	private static final String TAG="DownloadTaskManager";
	// UI请求队列
	private LinkedList<DownloadTask> downloadTasks;
	// 任务不能重复
	private Set<String> taskIdSet;

	private static DownloadTaskManager downloadTaskMananger;

	private DownloadTaskManager() {

		downloadTasks = new LinkedList<DownloadTask>();
		taskIdSet = new HashSet<String>();
		
	}

	public static synchronized DownloadTaskManager getInstance() {
		if (downloadTaskMananger == null) {
			downloadTaskMananger = new DownloadTaskManager();
		}
		return downloadTaskMananger;
	}

	//1.先执行
	public void addDownloadTask(DownloadTask downloadTask) {
		synchronized (downloadTasks) {
			if (!isTaskRepeat(downloadTask.getFileId())) {
				// 增加下载任务
				downloadTasks.addLast(downloadTask); 
			}
		}

	}
	public boolean isTaskRepeat(String fileId) {
		synchronized (taskIdSet) {
			if (taskIdSet.contains(fileId)) {
				return true;
			} else {
				System.out.println("下载管理器增加下载任务:"+ fileId);
				taskIdSet.add(fileId);
				return false;
			}
		}
	}
	
	public DownloadTask getDownloadTask() {
		synchronized (downloadTasks) {
			if (downloadTasks.size() > 0) {
				System.out.println("下载管理器增加下载任务:"+"取出任务");
				DownloadTask downloadTask = downloadTasks.removeFirst();
				return downloadTask;
			}
		}
		return null;
	}
}

其中downloadTasks表示的是线程队列,taskIdSet是任务队列,作用就是用来管理线程队列,此程序用的是去重操作。已经下载过的文件,不会再次下载。
3.线程池
DownloadTaskManagerThread.java
/**   
 * @Title: RequestTaskThread.java 
 * @Package com.kingsoft.filesystem 
 * @Description: TODO(用一句话描述该文件做什么) 
 * @author zengzhaoshuai zengzhaoshuai@kingsoft.com   
 * @date 2012-2-25 上午10:35:00 
 * @version V1.0   
 */
package com.threadExecutorService.test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class DownloadTaskManagerThread implements Runnable {

	private DownloadTaskManager downloadTaskManager;

	// 创建一个可重用固定线程数的线程池
	private ExecutorService pool;
	// 线程池大小
	private final int POOL_SIZE = 5;
	// 轮询时间
	private final int SLEEP_TIME = 1000;
	// 是否停止
	private boolean isStop = false;

	public DownloadTaskManagerThread() {
		downloadTaskManager = DownloadTaskManager.getInstance();
		pool = Executors.newFixedThreadPool(POOL_SIZE);

	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (!isStop) {
			DownloadTask downloadTask = downloadTaskManager.getDownloadTask();
			if (downloadTask != null) {
				pool.execute(downloadTask);
			} else {  //如果当前未有downloadTask在任务队列中
				try {
					// 查询任务完成失败的,重新加载任务队列
					// 轮询,
					Thread.sleep(SLEEP_TIME);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
		if (isStop) {
			pool.shutdown();
		}

	}

	/**
	 * @param isStop
	 *            the isStop to set
	 */
	public void setStop(boolean isStop) {
		this.isStop = isStop;
	}

}

3.测试类:Test.java
package com.threadExecutorService.test;

public class Test {
	public static void main(String[] args) {
		//1.new一个线程管理队列
		DownloadTaskManager.getInstance();
		//2.new一个线程池,并启动
		DownloadTaskManagerThread downloadTaskManagerThread = new DownloadTaskManagerThread();
		new Thread(downloadTaskManagerThread).start();

		//3.请求下载
		String []items=new String[]{"向晨宇1","向晨宇2","向晨宇3","向晨宇4","向晨宇5","向晨宇6","向晨宇7","向晨宇1","向晨宇2"};

		for(int i=0;i<items.length;i++){
			DownloadTaskManager downloadTaskMananger = DownloadTaskManager
					.getInstance();
			downloadTaskMananger.addDownloadTask(new DownloadTask(items[i]));
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

结果如下:


相同名字并不会继续执行,OK!~

【转载请注明出处,违者法律必究】  向晨宇 2012.5.10


       

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Android 线程池主要有以下四种类型: 1. FixedThreadPool:该线程池的线程数量是固定的,如果线程处于空闲状态,它们将会被保留在池,当任务到达时,它们会被立即执行。如果线程池的所有线程都处于忙碌状态,任务将会被放入到队列等待执行。 2. CachedThreadPool:该线程池的线程数量是不固定的,线程数会根据任务的多少自动调整。如果有大量任务需要执行,会创建更多的线程来处理这些任务,如果有较少的任务需要执行,线程池的线程数量会自动减少。 3. SingleThreadExecutor:该线程池只有一个线程,所有任务将会在这个线程按顺序执行。如果该线程因为异常而终止,那么将会创建一个新的线程来代替它。 4. ScheduledThreadPool:该线程池用于执行一些需要定时执行的任务,比如定时执行一些操作、周期性地执行某些任务等。 以下是一个使用 FixedThreadPool 的示例代码: ``` ExecutorService executorService = Executors.newFixedThreadPool(5); // 提交任务线程池执行 executorService.submit(new Runnable() { @Override public void run() { // 执行任务的代码 } }); // 关闭线程池 executorService.shutdown(); ``` 其他类型的线程池的使用方式与 FixedThreadPool 类似,只需要将 `Executors.newFixedThreadPool()` 替换为对应的方法即可。在使用线程池时,需要根据具体的业务需求选择合适的线程池类型。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值