The source code is for testing only and should not be used commercially. The source code comes from the Internet. If there is any infringement, please contact me to remove it.
Java 中的FutureTask 2

1. preface

The first two articles briefly analyzed Future interfaceand FutureTask this article will introduce FutureTask Use method.

2. Use of FutureTask

FutureTask There are two constructors, each passing in Runnale and Callable Examples. so FutureTask The use of is related to these two interfaces.

2.1 Combine Callable

CallableThe interface only defines one call()Methods, andRunnabletherun()Method, which has a return value, genericVThis is the type of result to be returned, and the execution results of subtasks can be returned. If you want to get the results of thread execution, use the Callable , and Callable Exceptions can be thrown. We define a simple task:

package cn.felord;
import java.util.concurrent.Callable;

/**
 * @author felord.cn
 * @since 2020/3/21 20:35
 */
public class MyTask implements Callable<Integer> {
    @Override
    public Integer call() {
        int total = 0;
        try {
            for (int i = 0; i < 10; i++) {
                System.out.println(" thread: " + Thread.currentThread().getName() + " i = " + i);
                Thread.sleep(1000);
                total += i;
            }
        } catch (InterruptedException e) {
            System.out.println("task is interrupted");
            //An exception is encountered and an interrupt is required to return to ensure that the thread is terminated
            return 0;
        }
        return total;
    }
}

And then below is in a main Template steps in the method:

    public static void main(String[] args) {
        //Step 1: Declare specific computing tasks
        MyTask myTask = new MyTask();
        //Step 2: Transfer the task to the initialization FutureTask
        FutureTask<Integer> futureTask = new FutureTask<>(myTask);
        //Step 3: Hand over FutureTask to a thread to execute
        Thread thread = new Thread(futureTask);

        thread.setName("future task thread");
        thread.start();

        try {
            Integer integer = futureTask.get();
            System.out.println("integer = " + integer);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println(" task is over ");

    }

After running, it seems to return expected values 45 , there seems to be no problem. But when we use the timeout mechanism, which is to change the code to get the result in the above code to laterInteger integer = futureTask.get(5000, TimeUnit.MILLISECONDS); The results were as follows:

 thread: future task thread i = 0
 thread: future task thread i = 1
 thread: future task thread i = 2
 thread: future task thread i = 3
 thread: future task thread i = 4
java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask.get(FutureTask.java:205)
    at cn.felord.Test.main(Test.java:26)
 thread: future task thread i = 5
 task is over 
 thread: future task thread i = 6
 thread: future task thread i = 7
 thread: future task thread i = 8
 thread: future task thread i = 9

We force the task to timeout, but the task's calculation thread is still calculating, so we need to handle the timeout exception or interrupt the calculation or continue get

A timeout for getting FutureTask results does not mean the end of the task. Moreover, it is usually not recommended to use the above methods for task calculation.

2.2 Combine Runnable and define the result

The structure is like this:

  public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
  }

At first I thought this result through runnable Calculated, but I was wrong:

   static final class RunnableAdapter<T> implements Callable<T> {
        final Runnable task;
        final T result;
        RunnableAdapter(Runnable task, T result) {
            this.task = task;
            this.result = result;
        }
        public T call() {
            task.run();
            return result;
        }
    }

this is Executors.callable At the bottom of the method, we cannot operate on it in threaded calculations result 。t quite understand JDK Why provide this "natural and egg" method. Run the given task and returngiven(is the parameter result you pass in, which means that the execution of the task has nothing to do with the given result.

2.3 Used with thread pool

We only use the above two methods in our research, and it is recommended to use a specific thread pool for general operating threads. Therefore, the following methods are orthodox use FutureTask Methods:

package cn.felord;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author dax
 * @since 2020/3/21 20:49
 */
public class Test {
    public static void main(String[] args) {
        //Step 1: Declare specific computing tasks
        MyTask myTask = new MyTask();

        //Step 2: Hand FutureTask to the thread pool for execution
        // ExecutorService pool = Executors.newCachedThreadPool();
        //It is generally recommended to use a custom thread pool or the thread pool provided by Spring to prevent OOM. The thread pool closure strategy should also be considered
        ExecutorService pool = newThreadPool();

        try {
        //Get results    
            Integer integer = pool.submit(myTask).get();
            System.out.println("integer = " + integer);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }


    private static ExecutorService newThreadPool() {
        ThreadFactory namedThreadFactory = new ThreadFactory() {
            final AtomicInteger sequence = new AtomicInteger(1);

            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r);
                int seq = this.sequence.getAndIncrement();
                thread.setName("future-task-thread" + (seq > 1 ? "-" + seq : ""));
                if (! thread.isDaemon()) {
                    thread.setDaemon(true);
                }

                return thread;
            }
        };
        return new ThreadPoolExecutor(5, 200,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024),
                namedThreadFactory,
                new ThreadPoolExecutor.AbortPolicy());
    }
}

Is this method safer and simpler?

3. the problems

  1. if a particular Callable anomalies were try-catch Be sure to return a result, otherwise the thread will continue execution.

  2. callget()Method blocks until the task has completed execution and does not return.

  3. get(long timeout, TimeUnit unit)Used to obtain execution results within a certain time. If it times out, subsequent code will continue to execute, and the calculation will not be interrupted.

  4. cancel(boolean mayInterruptIfRunning) The task may not be interrupted immediately, but you need to call the isDone or isCancelled Judging, it is safer to call the task thread's isInterrupted() Conduct interrupt status judgment.

4. summary

today FutureTask It lists the usage methods of, and also explains some misunderstandings that are easy to occur in use, hoping to help you. If you have any questions, you can leave a message to discuss it.

read more
Resource download
PriceFree
The use is limited to testing, experiments, and research purposes. It is prohibited for all commercial operations. This team is not responsible for any illegal behavior of users during use. Please self-test all source codes! There is no guarantee of the integrity and validity of your source code. All source code is collected from the entire network
Original link:https://bcbccb.cn/en/4480.html, please indicate the source for reprinting. Disclaimer: This resource has not been authorized by the original rights holder and is not commercially available. It can only be used to learn and analyze the underlying code, CSS, etc., and is prohibited for commercial purposes. Any relevant disputes and legal liabilities arising from unauthorized commercial use shall be fully borne by the user. Everyone is responsible to support genuine copies. Please delete them within 24 hours after downloading. Thank you for your support!
1

Comments0

最新盛大跑分系统源码多功能完美运营微信+支付宝+银行卡+云闪付+抢单系统跑分系统源码+完整数据
The latest Shanda running branch system source code is multi-functional and perfect operation WeChat + Alipay + bank card + cloud flash payment + order grabbing system running branch system source code + complete data
Someone bought it 6 minutes ago Go and have a look

Site Announcements

The source code (theme/plug-in/application source code) and other resources provided by this site are only for learning and exchange

Commercial use is prohibited, otherwise all consequences will be borne by the downloading user!

Some resources are collected or copied online. If they infringe on your legitimate rights and interests, please write to us.

Currently, members have a big reward, and the current price for a lifetime member is 299 gold coins.Recent price adjustments

Join quickly, opportunities wait for no one! immediately participated in

Captcha

Fast login to social accounts

en_USEnglish