In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "java multithreaded Callable and Future comparison". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
1. First of all, talk about how to create a thread.
Disadvantages of new Thread and implementing Runnable interface
(1) the performance of each new object created by new Thread is poor.
(2) lack of unified thread management, new threads may be created without restrictions, compete with each other, and may take up too many system resources to cause panic or oom.
(3) lack of more functions, such as regular execution, periodic execution, thread interruption.
(4) one of the biggest drawbacks is that these two methods can not obtain the execution results after the execution of the task.
(5) if you need to get the execution results, you must share variables or use thread communication to achieve the results, which is more troublesome to use.
2. Reasons for the emergence of Callable and Future
Since Java 1.5, Callable and Future have been provided, through which the results of task execution can be obtained after task execution is complete.
Introduction to Callable and Future
(1) the Callable interface represents a piece of code that can be called and return the result.
(2) the Future interface represents asynchronous tasks, which is the future result of tasks that have not yet been completed.
(3) so Callable is used to produce results and Future is used to obtain results.
The Callable interface uses generics to define its return type. The Executors class provides some useful ways to perform tasks within the Callable in the thread pool. Because the Callable task is parallel (parallel means that the whole appears to be parallel, but there is only one thread executing at some point in time), we have to wait for the result it returns.
Comparison between Callable and Runnable
Runnable is an interface in which only one run () method is declared:
Public interface Runnable {public abstract void run ();}
Because the return value of the run () method is of type void, no results can be returned after the task is executed.
Callable is located under the java.util.concurrent package, which is also an interface in which only one method is declared, but this method is called call ():
Public interface Callable {/ * * Computes a result, or throws an exception if unable to do so. * * [@ return] (https://my.oschina.net/u/556800) computed result * [@ throws] (https://my.oschina.net/throws) Exception if unable to compute a result * / V call () throws Exception;})
As you can see, this is a generic interface, and the type returned by the call () function is the V type passed in.
So how do you use Callable?
In general, it is used with ExecutorService. Several overloaded versions of submit methods are declared in the ExecutorService interface:
Future submit (Callable task); Future submit (Runnable task, T result); Future submit (Runnable task)
The parameter type in the first submit method is Callable
For the time being, you only need to know that Callable is generally used in conjunction with ExecutorService, and the specific usage will be described later. Generally, we use the first submit method and the third submit method, while the second submit method is rarely used.
Introduction of Future
Future is to cancel the execution result of a specific Runnable or Callable task, query whether it is completed, and obtain the result. If necessary, the execution result can be obtained through the get method, which blocks until the task returns the result.
The Future class, located under the java.util.concurrent package, is an interface:
Public interface Future {boolean cancel (boolean mayInterruptIfRunning); boolean isCancelled (); boolean isDone (); V get () throws InterruptedException, ExecutionException; V get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;}
Five methods are declared in the Future interface, and the following explains the role of each method in turn:
Cancel:
It is used to cancel the task, return true if the cancel task is successful, and return false if the cancel task fails. The parameter mayInterruptIfRunning indicates whether to cancel tasks that are in progress but are not finished, and if true is set, it means that tasks in progress can be canceled. If the task has been completed, whether mayInterruptIfRunning is true or false, this method must return false, that is, if canceling the completed task, it will return false;. If the task is executing, if mayInterruptIfRunning is set to true, it will return true. If mayInterruptIfRunning is set to false, it will return false;. If the task has not been executed, whether mayInterruptIfRunning is true or false, it will definitely return true.
IsCancelled:
Indicates whether the task was successfully cancelled, and returns true if it is successfully cancelled before the task completes normally.
IsDone:
Indicates whether the task has been completed. If the task is completed, return true.
Get ():
Used to get the execution result, this method creates blocking and does not return until the task has been executed.
Get (long timeout, TimeUnit unit): it is used to get the execution result. If the result has not been obtained within the specified time, it will directly return null.
In other words, Future provides three functions:
Judge whether the task is completed or not
Able to interrupt the task
Can get the result of task execution.
Because Future is only an interface, it cannot be used directly to create objects, so you have the following FutureTask.
FutureTask introduction
FutureTask implements the RunnableFuture interface, which is defined as follows:
Public interface RunnableFuture extends Runnable, Future {void run ();}
You can see that this interface implements the Runnable and Future interfaces, and the specific implementation in the interface is implemented by FutureTask. The two constructors for this class are as follows:
Public FutureTask (Callable callable) {if (callable = = null) throw new NullPointerException (); sync = new Sync (callable);} public FutureTask (Runnable runnable, V result) {sync = new Sync (Executors.callable (runnable, result);}
Two constructors are provided above, one taking Callable as an argument and the other taking Runnable as an argument. The association between these classes is very flexible for task modeling, allowing you to write the task as Callable based on FutureTask's Runnable feature (because it implements the Runnable interface), and then encapsulate it into a FutureTask that is scheduled by the executor and can be cancelled if necessary.
It is critical that the FutureTask can be scheduled by the executor. The methods it provides are basically a combination of Future and Runnable interfaces: get (), cancel, isDone (), isCancelled (), and run (), while the run () method is usually called by the executor, and we basically don't need to call it directly.
3. FutureTask instance public class MyCallable implements Callable {private long waitTime; public MyCallable (int timeInMillis) {this.waitTime=timeInMillis;} [@ Override] (https://my.oschina.net/u/1162528) public String call () throws Exception {Thread.sleep (waitTime); / / return the thread name executing this callable task return Thread.currentThread () .getName () }} public class FutureTaskExample {public static void main (String [] args) {ExecutorService executor = Executors.newFixedThreadPool (2); / / create thread pool and return ExecutorService instance MyCallable callable1 = new MyCallable (1000); / / tasks to be executed MyCallable callable2 = new MyCallable (2000); FutureTask futureTask1 = new FutureTask (callable1) / / encapsulate the task written by Callable into a FutureTask object scheduled by the executor FutureTask futureTask2 = new FutureTask (callable2); executor.execute (futureTask1); / / execute the task executor.execute (futureTask2), or execute the following method ExecutorService executor = Executors.newFixedThreadPool (2) / / create thread pool and return ExecutorService instance (singleton) MyCallable callable1 = new MyCallable (1000); / / Thread 1 MyCallable callable2 = new MyCallable (2000); Thread 2 Future S1 = executor.submit (callable1); / / create FutureTask and execute execute method Future S2 = executor.submit (callable2) / / creates FutureTask and executes the execute method while (true) {try {if (futureTask1.isDone () & & futureTask2.isDone ()) {/ / both tasks complete System.out.println ("Done"); executor.shutdown () / / close the thread pool and service return;} if (! futureTask1.isDone ()) {/ / Task 1 is not completed and will wait until the task is completed System.out.println ("FutureTask1 output=" + futureTask1.get ()) } System.out.println ("Waiting for FutureTask2 to complete"); String s = futureTask2.get (200L, TimeUnit.MILLISECONDS); if (s! = null) {System.out.println ("FutureTask2 output=" + s) } catch (InterruptedException | ExecutionException e) {e.printStackTrace ();} catch (TimeoutException e) {/ / do nothing}}
After running the above program, you can see that there is no output for a period of time, because the get () method waits for the task to complete before outputting the content.
The output is as follows:
FutureTask1 output=pool-1-thread-1Waiting for FutureTask2 to completeWaiting for FutureTask2 to completeWaiting for FutureTask2 to completeWaiting for FutureTask2 to completeWaiting for FutureTask2 to completeFutureTask2 output=pool-1-thread-2Done
To sum up, the emergence of Callable and Future is to make the thread controllable and return the results executed by the thread
Use examples in the project to import student information by multi-thread
1. Create thread pool / * Created by ds on 2017-6-29. * / [@ Component] (https://my.oschina.net/u/3907912)public class ThreadPool4ImportStudent {volatile private static ExecutorService instance = null; private ThreadPool4ImportStudent () {} public static ExecutorService getInstance () {try {if (instance! = null) {} else {Thread.sleep (300) Synchronized (ThreadPool4ImportStudent.class) {if (instance = = null) {instance = Executors.newFixedThreadPool (10);} catch (InterruptedException e) {e.printStackTrace ();} return instance;}}
The above method creates a thread pool and injects the relevant mapper classes
two。 Create thread public class ThreadImportStudents implements Callable {public static final String IMPORT_TYPE_STUDENT = "IMPORT_TYPE_STUDENT"; public static final String IMPORT_TYPE_VIP = "IMPORT_TYPE_VIP"; Log log_student = LogFactory.getLog ("student"); List ids = new ArrayList (); private String type; private Map allStudents; private List students; private Integer userId; private Integer vipRecordId; private boolean is_custom; private StudentImportRecord record; private Date date = new Date () Private Map importTemplateMap; private Integer companyId; private Integer schoolId; public ThreadImportStudents (String type, Map allStudents, Map importTemplateMap, List students, Integer userId, StudentImportRecord record, Integer vipRecordId, boolean is_custom, Integer companyId, Integer schoolId) {this.type = type; this.allStudents = allStudents; this.importTemplateMap = importTemplateMap This.students = students; this.userId = userId; this.record = record; this.vipRecordId = vipRecordId; this.is_custom = is_custom; this.companyId = companyId; this.schoolId = schoolId } [@ Override] (https://my.oschina.net/u/1162528) public List call () throws Exception {try {return insertOrUpdate ();} catch (Exception e) {e.printStackTrace ();} return null;}}
The above class is a thread class that adds students in batches, implements the Callable interface and overrides the call method, and returns all the id collections inserted into the students.
3. Business class controls threads List studentIds = new ArrayList (); List ids = new ArrayList (); Future stuId = ThreadPool4ImportStudent.getInstance (). Submit (new ThreadImportStudents (type, allStudents, importTemplateMap, student_list, userId, record, vo.getId (), is_custom, students.getCompanyId (), students.getSchoolId ()) through Future; ids.add (stuId) For (Future id:ids) {try {List idl=id.get (); if (idlchair null) {for (Integer idi:idl) {if (idi==null) {error++;}} studentIds.addAll (idl) }} catch (Exception e) {}} "comparison of java multithreaded Callable and Future" ends here. Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.