Multi-thread download has been around for a long time, such as flashget and NetAnts.
Protocol Support (the range field specifies the request content range). First, you can read the size of the requested content (that is, the file to be downloaded) and divide several blocks, the block is segmented and distributed to each thread for download. The thread downloads data from the beginning of the segment and ends with the end of the segment. The content downloaded by multiple threads will eventually be written to the same file.
Only useful, work requirements: to assign multiple tasks to multiple Java threads for execution, there will be a list of tasks assigned to the thread policy thinking: known: 1. A list of tasks to be executed, 2. specifies the number of threads to be started. The problem is: what tasks are actually executed by each thread.
Using Java multithreading to implement such a task distribution policy is: the task list is continuously segmented by the number of threads, first ensure the average number of tasks per thread can be allocated, the remaining tasks are appended to the thread in sequence from top to bottom-only in quantity, and the tasks actually executed by each thread are continuous. If there is a small amount of porridge (tasks), the number of threads actually started is equal to the number of tasks. Here, only each thread is able to scan the snow in front of its own door. After the fast completion of the action, it is impossible to see other threads tired again.
The implementation and Demo code is as follows: Implemented by three classes and written in a Java file: taskdistributor is the task distributor, task is the task to be executed, and workthread is the custom working thread. The command mode is used in the Code. If the listener can be configured, it would be even better to use the observer mode to control the UI display. Then, it will be able to realize the dynamic movement of block coloring jumps in the download, this defines the focus of the next step.
The Code contains more detailed annotations, which are easy to understand by reading these annotations and execution results. Main () is the test method
Package COM. alpha. thread; import Java. util. arraylist; import Java. util. list;/*** assign a task list to the thread distributor */public class taskdistributor {/*** test method ** @ Param ARGs */@ suppresswarnings ("unchecked ") public static void main (string [] ARGs) {// initialize the list of tasks to be executed tasklist = new arraylist (); For (INT I = 0; I <100; I ++) {tasklist. add (new task (I);} // set the number of worker threads to be started to four int threadcount = 4; list [] tasklistperthread = distribu Tetasks (tasklist, threadcount); system. out. println ("actual number of worker threads to be started:" + tasklistperthread. length); For (INT I = 0; I <tasklistperthread. length; I ++) {thread workthread = new workthread (tasklistperthread [I], I); workthread. start () ;}}/*** assigns tasks in the list to each thread and distributes them evenly first, how many elements (list) are appended to the array returned by the preceding thread in sequence) it indicates how many worker threads will be started ** @ Param tasklist * list of tasks to be dispatched * @ Param threadcount * Number of threads * @ return list array, each element contains a list of tasks to be executed by this thread */@ Suppresswarnings ("unchecked") public static list [] distributetasks (list tasklist, int threadcount) {// the minimum number of tasks to be executed by each thread, if it is not zero, each thread will be allocated to the task int mintaskcount = tasklist. size ()/threadcount; // The number of remaining tasks after the average allocation. If it is not zero, the task is appended to the previous thread by INT remaintaskcount = tasklist. size () % threadcount; // Number of threads to be started. If the number of worker threads is greater than that of the task, // you only need to start the worker threads with the same number as the task, one-to-one execution // after all, the thread pool is not implemented, so you do not need to initialize the sleeping thread int actualthreadcount = mintaskcount> 0? Threadcount: remaintaskcount; // array of threads to be started, and list of tasks to be executed by each thread [] tasklistperthread = new list [actualthreadcount]; int taskindex = 0; // redundant tasks after the average allocation, the number of remaining tasks after each append to a thread, re-declare the same variable as remaintaskcount //, otherwise the original value of remaintaskcount will be changed during execution, int remainindces = remaintaskcount; For (INT I = 0; I <tasklistperthread. length; I ++) {tasklistperthread [I] = new arraylist (); // if it is greater than zero, the thread must be allocated to the basic task if (mintaskcount> 0) {for (Int J = taskindex; j <mintaskcount + taskindex; j ++) {tasklistperthread [I]. add (tasklist. get (j);} taskindex + = mintaskcount;} // if there is any remaining one, add it to the thread if (remainindces> 0) {tasklistperthread [I]. add (tasklist. get (taskindex ++); remainindces --;} // print the task allocation status for (INT I = 0; I <tasklistperthread. length; I ++) {system. out. println ("Thread" + I + "task count:" + tasklistperthread [I]. size () + "range [" + (task) tasklistperthread [I]. get (0 )). gettaskid () + "," + (task) tasklistperthread [I]. get (tasklistperthread [I]. size ()-1 )). gettaskid () + "]");} return tasklistperthread ;}}
Package COM. alpha. thread;/*** the task to be executed, which can be changed to a certain State or called during execution. For example, a task has three states: Ready, running, and completed, by default, the ready state should be further improved. The Listener for task * can be added with state change, which determines the display of the UI */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; // declare the variable of a task's own business meaning, used to identify the task private int taskid; // The Initialization Method of the task public task (INT taskid) {This. status = ready; this. taskid = taskid;}/*** execution task */Public void execute () {// set the status to running setstatus (task. running); system. out. println ("the current thread ID is:" + thread. currentthread (). getname () + "| task id:" + this. taskid); // append a latency try {thread. sleep (1000);} catch (interruptedexception e) {e. printstacktrace () ;}// the execution is complete, and the status is set to complete setstatus (finished);} public void setstatus (INT status) {This. status = status;} public int gettaskid () {return taskid ;}}
Package COM. alpha. thread; import Java. util. list;/*** custom worker thread, holding the list of tasks assigned to it for execution */class workthread extends thread {// list of tasks to be executed by this thread, you can also specify the start value of the task index as private list <task> tasklist = NULL; @ suppresswarnings ("UNUSED") Private int threadid;/*** to construct a working thread, assign a task list and name the thread ID ** @ Param tasklist * list of tasks to be executed * @ Param threadid * thread ID */@ suppresswarnings ("unchecked ") public workthread (list tasklist, int threadid) {This. tasklist = tasklist; this. threadid = threadid;}/*** execute all assigned tasks */Public void run () {for (Task task: tasklist) using task.exe cute ();}}}
The execution result is as follows. Observe the number and interval of tasks assigned to each Java multithreading. The program ends after all threads have completed the assigned task:
Number of tasks of Thread 0: number of tasks of thread 1 in the 25 interval []: number of tasks of thread 2 in the 25 interval []: number of tasks of thread 3 in the 25 interval: number of worker threads to be started in the interval []: 4. The current thread ID is thread-0. | the task id is: 0. The current thread ID is: thread-3 | task id: 75 the current thread ID is: thread-1 | task id is: 25 the current thread ID is: thread-2 | task id is: 50 The current thread ID is: thread-1 | task id is: 26 the current thread ID is: thread-3 | task id is: 76 the current thread ID is: thread-0 | task id is: 1 The current thread ID is: thread-2 | task id is: 51
The above confession is only a basic effort, and it is really a joke to post it. There are more complex functions.
Java multi-thread download tools make full use of network resources, and Flash get and NetAnts have all been implemented: If a thread downloads the content of the segment to be allocated first, it will help other threads download unfinished data until the task is completed; or the Segment segment of a download thread is too small to be busy, which involves further task allocation. For another example, the above two tools can dynamically increase, decrease, or abort threads. The more complicated the tools are, the more complicated they are. These implementations may define various queues for implementation, for example, incomplete task queues, download task queues, and completed queues.
From: http://java.chinaitlab.com/line/792110.html