Java wrote multi-thread crawlers in 2007. At that time, its understanding of multithreading was limited to concurrent tasks, and it had no understanding of scheduling among multiple threads. Therefore, the subsequent multi-threaded applications are limited to only multi-threaded concurrent tasks. In fact, everything can be monitored in the thread.
Let's take a look at the column below to understand how to control multiple threads.
| The code is as follows: |
Copy code |
|
Package com. javaer. thread;
Public class PrintABC {
Public static Boolean isThreadA = true;
Public static Boolean isThreadB = false;
Public static Boolean isThreadC = false;
Public static void main (String [] args ){
Final PrintABC abc = new PrintABC ();
New Thread (new Runnable (){
Public void run (){
For (int I = 0; I <10; I ++ ){
Synchronized (abc ){
While (! IsThreadA ){
Try {
Abc. wait ();
} Catch (InterruptedException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}
System. out. print ("");
IsThreadA = false;
IsThreadB = true;
IsThreadC = false;
Abc. Policyall ();
}
}
}
}). Start ();
New Thread (new Runnable (){
Public void run (){
For (int I = 0; I <10; I ++ ){
Synchronized (abc ){
While (! IsThreadB ){
Try {
Abc. wait ();
} Catch (InterruptedException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}
System. out. print ("B ");
IsThreadA = false;
IsThreadB = false;
IsThreadC = true;
Abc. Policyall ();
}
}
}
}). Start ();
New Thread (new Runnable (){
Public void run (){
For (int I = 0; I <10; I ++ ){
Synchronized (abc ){
While (! IsThreadC ){
Try {
Abc. wait ();
} Catch (InterruptedException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}
System. out. print ("C ");
IsThreadA = true;
IsThreadB = false;
IsThreadC = false;
Abc. Policyall ();
}
}
}
}). Start ();
}
} |
The output result is as follows: ABCABCABCABCABC
Idea: The solution is probably like this. When three threads are enabled, each thread prints A letter at A time and prints it in A certain order. When printing A, other threads are in the blocking status, after printing A, unlock the thread and enable the thread that prints B. Other threads are in the blocking state. Similarly, when printing C, other threads are blocked. These three threads are in A sequential loop, in this way, ABC is printed multiple times in sequence.
This question seems to have a simple idea. In fact, we mainly need to use the wait () method and the notify () method, as well as the keyword synchronized. Only by fully understanding this can we solve this question. Below I need to explain these two methods, as well as the keyword synchronized.
The core feature of multi-thread parallel download is multipart and parallel download.
For example, if a file is 200 MB and has five threads, you can cut the file into five copies and separate them at the same time. Of course, the speed is much faster than the download speed.
| The code is as follows: |
Copy code |
|
Package com. javaer. examples. file;
Import java. io. File;
Import java. io. FileWriter;
Import java. io. IOException;
Import java. io. InputStream;
Import java. io. RandomAccessFile;
Import java.net. HttpURLConnection;
Import java.net. MalformedURLException;
Import java.net. URL;
Import java.net. URLConnection;
Public class MyMutilDown {
/**
* Single-threaded remote download
*/
Public void SingleDown (String filePath, String url ){
Try {
// File to be written
File file = new File (filePath + getFileExtName (url ));
FileWriter fWriter = new FileWriter (file );
URL ul = new URL (url );
URLConnection conn = ul. openConnection ();
Conn. setConnectTimeout (2000); // Request Timeout
// Int len = conn. getContentLength ();
InputStream in = conn. getInputStream ();
// Byte [] by = new byte [1, 1024];
Int temp = 0;
While (temp = in. read ())! =-1 ){
System. out. println (temp );
FWriter. write (temp );
}
FWriter. close ();
In. close ();
} Catch (MalformedURLException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
} Catch (IOException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}
/**
* File suffix
*
* @ Param path
* @ Return
*/
Public String getFileExtName (String path ){
Return path. substring (path. lastIndexOf ("."));
}
/**
* Multi-thread testing
*
* @ Param filePath
* File storage path
* @ Param url
* Url
* @ Param tnum
* Number of threads
*/
Public void MutiDown (String filePath, String url, int tnum ){
Try {
// File to be written
Final File file = new File (filePath + getFileExtName (url ));
System. out. println (file. getAbsolutePath ());
RandomAccessFile accessFile = new RandomAccessFile (file, "rwd"); // create a random access
Final URL ul = new URL (url );
HttpURLConnection conn = (HttpURLConnection) ul. openConnection ();
Conn. setConnectTimeout (2000); // Request Timeout
Conn. setRequestMethod ("GET ");
Int len = conn. getContentLength (); // file length
AccessFile. setLength (len );
AccessFile. close ();
Final int block = (len + tnum-1)/tnum; // The download speed of each thread
For (int I = 0; I <tnum; I ++ ){
Final int a = I;
New Thread (new Runnable (){
Int start = block * a; // start position
Int end = block * (a + 1)-1; // end position
@ Override
Public void run (){
HttpURLConnection conn2 = null;
RandomAccessFile accessFile2 = null;
InputStream in = null;
Try {
Conn2 = (HttpURLConnection) ul. openConnection ();
Conn2.setConnectTimeout (2000); // Request Timeout
Conn2.setRequestMethod ("GET ");
// TODO Auto-generated method stub
Conn2.setRequestProperty ("Range", "bytes =" + start
+ "-" + End + ""); // you can specify the attribute range of a common request.
In = conn2.getInputStream ();
Byte [] data = new byte [1024];
Int len = 0;
AccessFile2 = new RandomAccessFile (file, "rwd ");
AccessFile2.seek (start );
While (len = in. read (data ))! =-1 ){
System. out. println (a + "/" + len );
AccessFile2.write (data, 0, len); // concurrent write
}
System. out. println ("thread:" + a + "download complete! ");
} Catch (IOException e1 ){
// TODO Auto-generated catch block
E1.printStackTrace ();
} Finally {
Try {
AccessFile2.close ();
In. close ();
} Catch (IOException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}
}
}). Start ();
}
} Catch (MalformedURLException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
} Catch (IOException e ){
// TODO Auto-generated catch block
E. printStackTrace ();
}
}
/**
* @ Param args
* @ Throws IOException
*/
Public static void main (String [] args) throws IOException {
MyMutilDown mydown = new MyMutilDown ();
String path = "http://www.111cn.net/openx-220080603.rar ";
// Mydown. SingleDown ("/", path );
Mydown. MutiDown ("/bbc", path, 3 );
}
} |
Note: This article is copyrighted by lohasle, an ITeye member.