知识大全 任务列表分派给多个线程的策略和方法

Posted

篇首语:历史和哲学负有多种永恒的责任,同时也是简单的责任。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 任务列表分派给多个线程的策略和方法相关的知识,希望对你有一定的参考价值。

  多线程下载由来已久 如 FlashGet NetAnts 等工具 它们都是依懒于 HTTP 协议的支持(Range 字段指定请求内容范围) 首先能读取出请求内容 (即欲下载的文件) 的大小 划分出若干区块 把区块分段分发给每个线程去下载 线程从本段起始处下载数据及至段尾 多个线程下载的内容最终会写入到同一个文件中

  只研究有用的 工作中的需求 要把多个任务分派给多个线程去执行 这其中就会有一个任务列表指派到线程的策略思考 已知 一个待执行的任务列表 指定要启动的线程数;问题是 每个线程实际要执行哪些任务

  策略是 任务列表连续按线程数分段 先保证每线程平均能分配到的任务数 余下的任务从前至后依次附加到线程中 只是数量上 实际每个线程执行的任务都还是连续的 如果出现那种僧多(线程) 粥(任务) 少的情况 实际启动的线程数就等于任务数 一挑一 这里只实现了每个线程各扫自家门前雪 动作快的完成后眼见别的线程再累都是爱莫能助

  实现及演示代码如下 由三个类实现 写在了一个 java 文件中 TaskDistributor 为任务分发器 Task 为待执行的任务 WorkThread 为自定的工作线程 代码中运用了命令模式 如若能配以监听器 用上观察者模式来控制 UI 显示就更绝妙不过了 就能实现像下载中的区块着色跳跃的动感了 在此定义下一步的着眼点了

  代码中有较为详细的注释 看这些注释和执行结果就很容易理解的 main() 是测试方法

    package mon;   import java util ArrayList;   import java util List;   /**   * 指派任务列表给线程的分发器   * @author Unmi   * QQ:   Email:    * MSN:     */   public class TaskDistributor    /**   * 测试方法   * @param args   */   public static void main(String[] args)    //初始化要执行的任务列表   List taskList = new ArrayList();   for (int i =  ; i <  ; i++)    taskList add(new Task(i));      //设定要启动的工作线程数为   个   int threadCount =  ;   List[] taskListPerThread = distributeTasks(taskList  threadCount);   System out println( 实际要启动的工作线程数 +taskListPerThread length);   for (int i =  ; i < taskListPerThread length; i++)    Thread workThread = new WorkThread(taskListPerThread[i] i);   workThread start();         /**   * 把 List 中的任务分配给每个线程 先平均分配 剩于的依次附加给前面的线程   * 返回的数组有多少个元素 (List) 就表明将启动多少个工作线程   * @param taskList 待分派的任务列表   * @param threadCount 线程数   * @return 列表的数组 每个元素中存有该线程要执行的任务列表   */   public static List[] distributeTasks(List taskList  int threadCount)    // 每个线程至少要执行的任务数 假如不为零则表示每个线程都会分配到任务   int minTaskCount = taskList size() / threadCount;   // 平均分配后还剩下的任务数 不为零则还有任务依个附加到前面的线程中   int remainTaskCount = taskList size() % threadCount;   // 实际要启动的线程数 如果工作线程比任务还多   // 自然只需要启动与任务相同个数的工作线程 一对一的执行   // 毕竟不打算实现了线程池 所以用不着预先初始化好休眠的线程   int actualThreadCount = minTaskCount >   ? threadCount : remainTaskCount;   // 要启动的线程数组 以及每个线程要执行的任务列表   List[] taskListPerThread = new List[actualThreadCount];   int taskIndex =  ;   //平均分配后多余任务 每附加给一个线程后的剩余数 重新声明与 remainTaskCount   //相同的变量 不然会在执行中改变 remainTaskCount 原有值 产生麻烦   int remainIndces = remainTaskCount;   for (int i =  ; i < taskListPerThread length; i++)    taskListPerThread[i] = new ArrayList();   // 如果大于零 线程要分配到基本的任务   if (minTaskCount >  )    for (int j = taskIndex; j < minTaskCount + taskIndex; j++)    taskListPerThread[i] add(taskList get(j));      taskIndex += minTaskCount;      // 假如还有剩下的 则补一个到这个线程中   if (remainIndces >  )    taskListPerThread[i] add(taskList get(taskIndex++));   remainIndces ;         // 打印任务的分配情况   for (int i =  ; i < taskListPerThread length; i++)    System out println( 线程   + i +   的任务数  +    taskListPerThread[i] size() +   区间[   + taskListPerThread[i] get( ) getTaskId() +    + taskListPerThread[i] get(taskListPerThread[i] size()    ) getTaskId() +  ] );      return taskListPerThread;         /**   * 要执行的任务 可在执行时改变它的某个状态或调用它的某个操作   * 例如任务有三个状态 就绪 运行 完成 默认为就绪态   * 要进一步完善 可为 Task 加上状态变迁的监听器 因之决定UI的显示   */   class Task    public static final int READY =  ;   public static final int RUNNING =  ;   public static final int FINISHED =  ;   private int status;   //声明一个任务的自有业务含义的变量 用于标识任务   private int taskId;   //任务的初始化方法   public Task(int taskId)   this status = READY;   this taskId = taskId;      /**   * 执行任务   */   public void execute()    // 设置状态为运行中   setStatus(Task RUNNING);   System out println( 当前线程 ID 是  + Thread currentThread() getName()   +  | 任务 ID 是 +this taskId);   // 附加一个延时   try    Thread sleep( );    catch (InterruptedException e)    e printStackTrace();      // 执行完成 改状态为完成   setStatus(FINISHED);      public void setStatus(int status)    this status = status;      public int getTaskId()    return taskId;         /**   * 自定义的工作线程 持有分派给它执行的任务列表   */   class WorkThread extends Thread    //本线程待执行的任务列表 你也可以指为任务索引的起始值   private List taskList = null;   private int threadId;   /**   * 构造工作线程 为其指派任务列表 及命名线程 ID   * @param taskList 欲执行的任务列表   * @param threadId 线程 ID   */   public WorkThread(List taskList int threadId)    this taskList = taskList;   this threadId = threadId;      /**   * 执行被指派的所有任务   */   public void run()    for (Task task : taskList)    task execute();         

  执行结果如下 注意观察每个线程分配到的任务数量及区间 直到所有的线程完成了所分配到的任务后程序结束

       线程   的任务数  区间[ ]   线程   的任务数  区间[ ]   线程   的任务数  区间[ ]   线程   的任务数  区间[ ]   线程   的任务数  区间[ ]   实际要启动的工作线程数   当前线程 ID 是 Thread  | 任务 ID 是   当前线程 ID 是 Thread  | 任务 ID 是   当前线程 ID 是 Thread  | 任务 ID 是   当前线程 ID 是 Thread  | 任务 ID 是   当前线程 ID 是 Thread  | 任务 ID 是   当前线程 ID 是 Thread  | 任务 ID 是   当前线程 ID 是 Thread  | 任务 ID 是   当前线程 ID 是 Thread  | 任务 ID 是

  

  上面坦白来只算是基本功夫 贴出来还真见笑了 还有更为复杂的功能

cha138/Article/program/Java/gj/201311/27458

相关参考

施工负责人在分派生产任务时,应对( )进行书面安全技术交底。

施工负责人在分派生产任务时,应对()进行书面安全技术交底。A.班组长B.相关管理人员C.分包单位安全员D.施工作业人员E.分包单位技术负责人【正确答案】BD

接受批评(2)按要求做(3)分派任务(4)出现失误(5)改进工作__

接受批评(2)按要求做(3)分派任务(4)出现失误(5)改进工作_____A、4——1——2——5——3B、2——5——3——4——1C、3-2-4-1-5D、2-3-5-4-1答案:C解析:(3)分

知识大全 强大的多线程和倒计时程序

  多线程技术是非常实用的技术特别是碰到有关运行多个任务的程序就只有多线程才能满足你的要求在以下程序中我所展示的是一个倒计时程序及利用Callable接口(不是Runnable接口)来返回一个你所要求

知识大全 多线程

  在计算机编程中一个基本的概念就是同时对多个任务加以控制许多程序设计问题都要求程序能够停下手头的工作改为处理其他一些问题再返回主进程可以通过多种途径达到这个目的最开始的时候那些拥有机器低级知识的程序

知识大全 Java多线程如何创建多个线程

Java多线程如何创建多个线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java多线程的同

领导考虑分派a、h两人执行一项特殊任务,经过讨论,有四个建议:①选择a但不选择b;②或者不选择a,或者选择b;③如果选择

领导考虑分派a、h两人执行一项特殊任务,经过讨论,有四个建议:①选择a但不选择b;②或者不选择a,或者选择b;③如果选择b,则选择a;④选择b,但不选择a。据此,可以断定,不可能由同一个人提出的建议是

知识大全 制作多个线程

  现在考虑一下创建多个不同的线程的问题我们不可用前面的例子来做到这一点所以必须倒退回去利用从Thread继承的多个独立类来封装run()但这是一种更常规的方案而且更易理解所以尽管前例揭示了我们经常都

知识大全 多线程对多个客户端的监听

  这是一个比较简单的例子来说明socket编程服务器端使用了多线程来监听客户端  服务器端的代码  packageSocketTest;  importjavaio*;  import*;  imp

知识大全 使用Java多线程实现任务分发

使用Java多线程实现任务分发  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  多线程下载由来已久

知识大全 解析php多线程下载远程多个文件

functionremote($urls$name=$path=$dir=/images/)if(!is_array($urls)orcount($urls)==)returnfalse;dmkdir