JAVA多线程——实现任务分发

本文代码来自网络,我自己按理解重新贴一下。
来源

网址:http://blog.51cto.com/gggcgba/1437919


本文主要实现在多任务下,如何指定线程分发任务。比如100条任务,分发给四个线程。
想要实现的效果如下:
线程1执行任务第0——24    
线程2执行任务第25——49   
线程3执行任务第50——74  
线程4执行任务75——99

具体实现方法如下。

包含三个类:任务分发类、任务类、线程执行类
定义任务类:
execute()方法是想要执行的具体业务。
package com.alpha.thread;

public class Task {
    public static final int READY = 0;  
    public static final int RUNNING = 1;  
    public static final int FINISHED = 2;  

    @SuppressWarnings("unused")  
    private int status;  
    // 声明一个任务的自有业务含义的变量,用于标识任务  
    private int taskId;  
    
    private String storeCode;

    // 任务的初始化方法  
    public Task(int taskId,String storeCode) {  
        this.status = READY;  
        this.taskId = taskId;  
        this.storeCode=storeCode;
    }  

    /** 
     * 执行任务 
     */  
    public void execute() {  
        // 设置状态为运行中  
        setStatus(Task.RUNNING);  
        System.out.println("当前线程 ID 是:" + Thread.currentThread().getName()  
                + " | 任务 ID 是:" + this.taskId+"  |门店号为:"+this.storeCode);  
        // 附加一个延时  
        try {  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        // 执行完成,改状态为完成  
        setStatus(FINISHED);  
    }  

    public void setStatus(int status) {  
        this.status = status;  
    }  

    public int getTaskId() {  
        return taskId;  
    }  
}


线程执行类:重新实现Thread类,构造工作线程,为其指派任务列表,及命名线程 ID。


package com.alpha.thread;

import java.util.List;

public class WorkThread extends Thread{
	// 本线程待执行的任务列表,你也可以指为任务索引的起始值  
    private List<Task> taskList = null;  
    @SuppressWarnings("unused")  
    private int threadId;  

    /** 
     * 构造工作线程,为其指派任务列表,及命名线程 ID 
     *  
     * @param taskList 
     *            欲执行的任务列表 
     * @param threadId 
     *            线程 ID 
     */  
    @SuppressWarnings("unchecked")  
    public WorkThread(List taskList, int threadId) {  
        this.taskList = taskList;  
        this.threadId = threadId;  
    }  

  
    /** 
     * 执行被指派的所有任务 
     */  
    public void run() {  
        for (Task task : taskList) {  
            task.execute();  
        }  
    }  
}


任务分发类:
package com.alpha.thread;

import java.util.ArrayList;
import java.util.List;

public class TaskDistributor {
	
	 /** 

     * 测试方法 

     * @param args 

     */  

    @SuppressWarnings("unchecked")  
    public static void main(String[] args) {  
        // 初始化要执行的任务列表  
        List taskList = new ArrayList();  
        for (int i = 0; i < 100; i++) {  
            taskList.add(new Task(i,i+":store"));  
        }  
        // 设定要启动的工作线程数为 4 个  
        int threadCount = 4;  
        List[] taskListPerThread = distributeTasks(taskList, threadCount);  
        System.out.println("实际要启动的工作线程数:" + taskListPerThread.length);  
        for (int i = 0; i < taskListPerThread.length; i++) {  
            Thread workThread = new WorkThread(taskListPerThread[i], i);  
            workThread.start();  
        }  

    }  

	
	
	
	@SuppressWarnings("unchecked")
	public static List[] distributeTasks(List taskList, int threadCount) {  

        // 每个线程至少要执行的任务数,假如不为零则表示每个线程都会分配到任务  
        int minTaskCount = taskList.size() / threadCount;  
        // 平均分配后还剩下的任务数,不为零则还有任务依个附加到前面的线程中  
        int remainTaskCount = taskList.size() % threadCount;  
        // 实际要启动的线程数,如果工作线程比任务还多  
        // 自然只需要启动与任务相同个数的工作线程,一对一的执行  
        // 毕竟不打算实现了线程池,所以用不着预先初始化好休眠的线程  
        int actualThreadCount = minTaskCount > 0 ? threadCount:remainTaskCount;  

        // 要启动的线程数组,以及每个线程要执行的任务列表  
        List[] taskListPerThread = new List[actualThreadCount];  
        int taskIndex = 0;  
        // 平均分配后多余任务,每附加给一个线程后的剩余数,重新声明与 remainTaskCount  
        // 相同的变量,不然会在执行中改变 remainTaskCount 原有值,产生麻烦  
        int remainIndces = remainTaskCount;  
        for (int i = 0; i < taskListPerThread.length; i++) {  
            taskListPerThread[i] = new ArrayList();  
            // 如果大于零,线程要分配到基本的任务  
            if (minTaskCount > 0) {  
                for (int j = taskIndex; j < minTaskCount + taskIndex; j++) {  
                    taskListPerThread[i].add(taskList.get(j));  
                }  
                taskIndex += minTaskCount;  
            }  
            // 假如还有剩下的,则补一个到这个线程中  
            if (remainIndces > 0) {  
                taskListPerThread[i].add(taskList.get(taskIndex++));  
                remainIndces--;  
            }  
        }  

        // 打印任务的分配情况  
        for (int i = 0; i < taskListPerThread.length; i++) {  
            System.out.println("线程 "+i+ "的任务数:" + taskListPerThread[i].size()+ " 区间["  
                    + ((Task) taskListPerThread[i].get(0)).getTaskId()  
                    + ","  
                    + ((Task) taskListPerThread[i].get(taskListPerThread[i].size() - 1))  
                            .getTaskId() + "]");  
        }  
        return taskListPerThread;  
    }  
}  


执行结果:
线程 0的任务数:25 区间[0,24]
线程 1的任务数:25 区间[25,49]
线程 2的任务数:25 区间[50,74]
线程 3的任务数:25 区间[75,99]
实际要启动的工作线程数:4
当前线程 ID 是:Thread-0 | 任务 ID 是:0  |门店号为:0:store
当前线程 ID 是:Thread-1 | 任务 ID 是:25  |门店号为:25:store
当前线程 ID 是:Thread-2 | 任务 ID 是:50  |门店号为:50:store
当前线程 ID 是:Thread-3 | 任务 ID 是:75  |门店号为:75:store
当前线程 ID 是:Thread-0 | 任务 ID 是:1  |门店号为:1:store
当前线程 ID 是:Thread-1 | 任务 ID 是:26  |门店号为:26:store
当前线程 ID 是:Thread-2 | 任务 ID 是:51  |门店号为:51:store
当前线程 ID 是:Thread-3 | 任务 ID 是:76  |门店号为:76:store
当前线程 ID 是:Thread-0 | 任务 ID 是:2  |门店号为:2:store
当前线程 ID 是:Thread-1 | 任务 ID 是:27  |门店号为:27:store
当前线程 ID 是:Thread-2 | 任务 ID 是:52  |门店号为:52:store
当前线程 ID 是:Thread-3 | 任务 ID 是:77  |门店号为:77:store
当前线程 ID 是:Thread-0 | 任务 ID 是:3  |门店号为:3:store


猜你喜欢

转载自blog.csdn.net/mubing870825/article/details/79876896
今日推荐