Knowledge added: multi-threaded third way
Source: http: //www.threadworld.cn/archives/39.html
Creating a thread in two ways, one is the direct successor Thread, another is to achieve Runnable interface. Both methods have a defect: Unable to get the results after performing the task. If you need to get the results, it is necessary to achieve the effect by way of the use of shared variables or thread communication, so use them more trouble. And since the beginning of Java 1.5, it provides a Callable and Future, task execution results can be obtained after the task is completed by them.
A, Runnable Interface
Java.lang.Runnable look at it, it is an interface, in it only declares a run () method:
Since the run () method returns a value of type void, so I can not return any results after performing the task.
Two, Callable Interface
Callable interface is located under the java.util.concurrent package, in it only declares a method, but this method is called call ().
Can be seen, this is a generic interface, Call () function returns the type passed in is the type V. Callable interface can be seen as complementary to the Runnable interface, Call method with a return value, and may throw an exception.
Three, FutureTask class
How to get Callable return the result? Generally through the intermediary of this FutureTask achieved. The whole process is this:
the Callable instance as a parameter to generate an object FutureTask then this object as a Runnable, as an argument from another thread.
3.1 FutureTask structure
3.2 FutureTask start
due FutureTask implements Runnable, and therefore both can be directly executed by Thread packaging, it can also be submitted to the Executive ExecuteService
Four, Future interfaces
FutureTask core interface inheritance hierarchy is the Future. Future core idea is: a method, the calculation process can be very time consuming, wait method returns, apparently unwise. When calling the method can, immediately returns a Future, possible to control the calculation process by the method f Future this data structure.
Here the control comprises:
GET methods: obtaining the calculation result (if not finished computing, also must wait)
Cancel Method: calculation not finished, the calculation process can be canceled
isDone Method: After determining whether calculation
isCancelled Method: determining whether the calculation is canceled
example
public class ThreadMain { public static void main(String[] args) throws Exception, ExecutionException { ThreadTest threadTest = new ThreadTest();//线程任务 // FutureTask接收线程的返回数据 FutureTask<String> f = new FutureTask<>(threadTest); Thread thread = new Thread(f); thread.start(); String res = f.get(); System.out.println(res); } } class ThreadTest implements Callable<String>{ @Override public String call() throws Exception { return "hello"; } }
A. Word count Case
The use of multi-threading, write the number of different threads statistics different files of words, the outcome of the survey data to the specified intermediate file summary statistics of the number of words.
Client:
public class MyClient implements Callable<String>{ //不同线程处理不同的文件 String localFilePath ; public MyClient(String localFilePath) { super(); this.localFilePath = localFilePath; } public static final String KEY = "天王盖地虎"; public static final String PATH = "E:/javafile/wc_server.jar"; @SuppressWarnings("unused") private String task() throws Exception{ String res = Null ; the Socket socket = new new the Socket ( " 127.0.0.1 " , 8888 ); ObjectOutputStream OOS = new new ObjectOutputStream (Socket.getOutputStream ()); ObjectInputStream OIS = new new ObjectInputStream (Socket.getInputStream ()); // 1 sending school identity test oos.writeObject (KEY); // 2 receives the check result Boolean B = (Boolean) ois.readObject (); IF (B) { // check the success of the System. OUT .println (" The verification is successful " ); // 3 transmits the server storage jar package path oos.writeObject (the PATH); // . 4 transmits to the server packet jar @ 4.1 jar package needs to read the local BufferedInputStream BIS = new new BufferedInputStream ( new new the FileInputStream ( " E: /javafile/wc.jar " )); byte [] = BS new new byte [ 1024 ]; int len; the while ((len = bis.read (BS)) = -! . 1 ) { // 4.2 this jar using the network packet stream transmitted oos.write (BS, 0 , len); } oos.flush (); bis.close (); // send to the server Run String cmd = " Java -jar " + the PATH + " " + localFilePath; oos.writeObject (cmd); // receiving server jar execution result RES = (String) ois.readObject (); // System.out.println (RES); } the else { . the System OUT .println ( " the verification fails " ); } the Socket.close (); return res; } @Override public String call() throws Exception { String res = task(); return res; } }
Server
public class MyServer { public static final String KEY = "天王盖地虎"; public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(8888); while(true) { Socket socket = ss.accept(); OutputStream os = socket.getOutputStream(); InputStream in = socket.getInputStream(); ObjectInputStream ois = new new ObjectInputStream ( in ); ObjectOutputStream OOS = new new ObjectOutputStream (os); // sent by a client's identity verification String str = (String) ois.readObject (); // check the success of IF (key.equals (str) ) { oos.writeObject ( to true ); // receive path String path = (String) ois.readObject (); // receiving jar package, and written to the specified path BufferedOutputStream the BOS = new new BufferedOutputStream the ( new new FileOutputStream(path)); byte[] bs = new byte[1024]; int len = 0; while((len = ois.read(bs)) != -1) { bos.write(bs,0,len); } bos.flush(); bos.close(); // 接收执行命令 String cmd = (String)ois.readObject(); Runtime runtime = Runtime.getRuntime(); Process p = runtime.exec(cmd); InputStream the InputStream = p.getInputStream (); the BufferedReader br = new new the BufferedReader ( new new the InputStreamReader (inputStream)); String Line = null ; the StringBuilder RES = new new the StringBuilder (); the while (! (= Br.readLine Line ()) = null ) { res.append (Line + " \ R & lt \ n- " ); } // return the results to the client check fails oos.writeObject(res.toString()); oos.flush (); // } the else { // returns the results to the client oos.writeObject ( to false ); } } } }
Multithreading statistics
public class the TestClient { public static void main (String [] args) throws Exception { // Create a thread first task MyClient to M1 = new new MyClient to ( " E: /javafile/wc1.txt " ); a FutureTask, <String> F1 = new new a FutureTask, <> (M1); new new the thread (F1) .start (); String RES1 = F1. GET (); // System.out.println ( "results of the thread 1:" + "/ r / n " + res1 ); // create a second thread task MyClient M2 = new new MyClient ( "E: /javafile/wc2.txt " ); a FutureTask, <String> F2 = new new a FutureTask, <> (M2); new new the Thread (F2) .start (); String RES2 = F2. GET (); // System.out. println ( "results of the thread 2:" + RES2); // summary results data ---> intermediate results written // appends the result to the specified data file BufferedWriter, BW = new new BufferedWriter, ( new new FileWriter ( new new file ( " E: /javafile/res.res " ), to true )); bw.write (res1); bw.write (RES2, 0, res2.length()-2); //bw.write(res2); bw.close(); //统计结果数据 Map<String,Integer> map = new HashMap<>() ; BufferedReader br = new BufferedReader(new FileReader("E:/javafile/res.res")); String line = null ; while((line = br.readLine())!=null){ System.out.println(line); String[] split = line.split(":"); String word = split[0]; int num = Integer.parseInt(split[1]); Integer num2 = map.getOrDefault(word, 0); num2+=num; map.put(word, num2); } Set<Entry<String, Integer>> entrySet = map.entrySet(); for (Entry<String, Integer> entry : entrySet) { System.out.println(entry); } } }