In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
Editor to share with you how to use Future and FutureTask in Java. I hope you will get something after reading this article. Let's discuss it together.
I. Future interface
When the call () method completes, the results must be stored in an object known to the main thread so that the main thread can know the results returned by that thread. To do this, you can use the Future object.
Think of Future as the object that saves the results-it may not save the results for the time being, but it will save them in the future (once the Callable returns). Future is basically a way in which the main thread can track progress and the results of other threads. To implement this interface, five methods must be overridden. Important methods are listed here, as follows:
Public boolean isDone ()
Public boolean cancel (boolean mayInterruptIfRunning)
Used to stop the task. If it has not been started, it will stop the task. If started, the task is interrupted only if mayInterrupt is true.
Boolean isCancelled ()
If the task is cancelled before the normal end, return to true
Public V get () throws InterruptedException, ExecutionException
Used to get the results of the task. If the task completes, it will immediately return the result, otherwise it will wait for the task to complete, and then return the result.
Public V get (long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
Returns true if the task is complete, false otherwise.
Callable is similar to Runnable in that it encapsulates a task to run on another thread, while Future is used to store results obtained from another thread.
In fact, Future can also be used with Runnable. To create a thread, you need Runnable. To get the results, you need future.
II. FutureTask
Description: FutureTask can be used when a thread needs to wait for another thread to finish executing a task before it can continue execution. Suppose there are multiple threads performing several tasks, and each task can only be executed at most once. When multiple threads try to execute the same task at the same time, only one thread is allowed to execute the task, and other threads need to wait for the task to finish before continuing.
The Java library has a specific FutureTask type that implements Runnable and Future and easily combines the two functions. You can create a FutureTask by providing Callable for its constructor. The FutureTask object is then supplied to the constructor of Thread to create the Thread object. Therefore, threads are created indirectly using Callable.
FutureTask state transition
FutureTask has the following seven states:
The running status of the FutureTask task, initially NEW. The running state is converted to the terminal state only in the set, setException, and cancel methods. During completion, the state may present an instantaneous value of INTERRUPTING (only if running the program is interrupted to satisfy * * cancel (true) * *) or COMPLETING (when setting the result). The transition from these intermediate states to the final state uses a lower-cost ordered / delayed write because the values are uniform and need to be further modified.
State: indicates the running status of the current task. All the methods of FutureTask revolve around state. State is declared as volatile, which ensures the visibility of state, and all threads will see it when making changes to state.
NEW: represents a new task, initial state
COMPLETING: when the task is set to the result, it is in the COMPLETING state, which is an intermediate state.
NORMAL: indicates that the task ends normally.
EXCEPTIONAL: indicates that the task ended with an exception
CANCELLED: the cancel (true) method is called before the task is executed, and the task is in CANCELLED
INTERRUPTING: when a task calls the cancel (true) interrupt program, the task is in the INTERRUPTING state, which is an intermediate state.
INTERRUPTED: when the task calls cancel (true) to interrupt the program, the interrupt () method is called to interrupt the thread, and the task state is changed from INTERRUPTING to INTERRUPTED.
Possible state transitions:
1. NEW-> COMPLETING-> NORMAL: ends normally
2. NEW-> COMPLETING-> EXCEPTIONAL: abnormal end
3. NEW-> CANCELLED: task is cancelled
4. NEW-> INTERRUPTING-> INTERRUPTED: task is interrupted
Third, use Callable and Future
One of the missing features of Runnable is that when a thread terminates (that is, when run () is complete), we cannot get the thread to return the result.
To support this feature, the Callable interface is provided in Java. You cannot directly replace runnable because the constructor of the Thread class has no Callable at all.
So we can find a middleman, namely FutureTask.
Case
Class MyThreadA implements Callable {@ Override public Object call () throws Exception {System.out.println (Thread.currentThread (). GetName () + "in the call method"); System.out.println (Thread.currentThread (). GetName () + "Thread enters the call method and begins to sleep (some calculations are done)"; Thread.sleep (10000); System.out.println (Thread.currentThread (). GetName () + "awake") Return Thread.currentThread () .getName () + "returned:" + System.currentTimeMillis ();}} public class demo1 {public static void main (String [] args) throws ExecutionException, InterruptedException {FutureTask futureTaskA = new FutureTask (new MyThreadA ()); FutureTask futureTaskB = new FutureTask (()-> {System.out.println (Thread.currentThread (). GetName () + "in call method") Return Thread.currentThread () .getName () + "returned:" + System.currentTimeMillis ();}); new Thread (futureTaskA, "thread A") .start (); new Thread (futureTaskB, "thread B") .start (); while (! futureTaskB.isDone ()) {/ / isDone indicates whether the calculation of FutureTask completes System.out.println ("wait.") } System.out.println (futureTaskA.get ()); System.out.println (futureTaskB.get ()); System.out.println (Thread.currentThread (). GetName () + "over");}}
Output result:
The time difference between the two threads in the above figure is about 10 seconds. It can be seen that when a thread (thread B) needs to wait (always wait … FutureTask can be used when another thread (thread A) finishes executing a task (doing some calculations) before it can continue to execute. No matter who is in front of futureTaskA.get () or futureTaskB.get (), the output must be "thread B returned: xxx" in "wait..." In the back of. Suppose there are multiple threads performing several tasks, and each task can only be executed at most once. When multiple threads try to execute the same task at the same time, only one thread is allowed to execute the task, and other threads need to wait for the task to finish before continuing.
Summary (FutureTask core principle)
Core principle of FutureTask
When you need to perform time-consuming operations in the main thread, but do not want to block the main thread, you can give these jobs to the Future object to complete in the background. When the main thread needs it in the future, you can get the calculation results or execution status of the background job through the Future object.
FutureTask is usually used for time-consuming computing, and the main thread can get the results after completing its own task.
The results can be retrieved only when the calculation is complete; if the calculation has not been completed, the get method is blocked. Once the calculation is complete, you cannot restart or cancel the calculation. The get method gets the result only when the calculation is complete, otherwise it will block until the task is completed, and then return the result or throw an exception.
Get is calculated only once, so the get method is placed last.
Attachment: FutureTask ensures that the task is executed only once in a highly concurrent environment
There is an example on the Internet, but the middle is not very clear. I rearranged it.
In many high concurrency environments, we often only need to perform certain tasks once. The features of this usage scenario FutureTask are just right. For example, suppose there is a connection pool with key. When key exists, the object corresponding to key is returned directly; when key does not exist, a connection is created. For such an application scenario, the usual method is to use a Map object to store the corresponding relationship between key and connection pool. The typical code is shown below:
Package com.concurrency.chapter15;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReentrantLock;/** * @ program: error example * * @ description: in many high concurrency environments, we often only need to perform certain tasks once. * the features of this usage scenario FutureTask are competent. For example, suppose there is a connection pool with key. * when key exists, the object corresponding to key is returned directly; when key does not exist, a connection is created. For such an application scenario, * the usual method is to use a Map object to store the corresponding relationship between key and connection pool. The typical code is as follows * in this example, we ensure thread safety in a high concurrency environment and ensure that the connection is created only once, but at the expense of performance. * * @ author: zhouzhixiang * @ create: 2019-05-14 20:22 * / public class FutureTaskConnection1 {private static Map connectionPool = new HashMap (); private static ReentrantLock lock = new ReentrantLock (); public static Connection getConnection (String key) {try {lock.lock (); Connection connection = connectionPool.get (key); if (connection = = null) {Connection newConnection = createConnection () ConnectionPool.put (key, newConnection); return newConnection;} return connection;} finally {lock.unlock ();} private static Connection createConnection () {try {return DriverManager.getConnection (");} catch (SQLException e) {e.printStackTrace () } return null;}} after reading this article, I believe you have some understanding of "how to use Future and FutureTask in Java". If you want to know more about it, you are welcome to follow the industry information channel. Thank you for reading!
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.