Cet article présente principalement en détail le pool de threads de concurrence Callable et Future of Java, qui a une certaine valeur de référence. Les amis intéressés peuvent se référer à
Introduction à Callable et Future
<.>
1. Callable
lancer une exception. Pour faciliter la compréhension, nous pouvons comparer Callable à une interface Runnable, et la méthode call() de Callable est similaire à la méthode run() de Runnable.
Le code source de Callable est le suivant :
public interface Callable<V> { V call() throws Exception; }
Explication : De là, nous pouvons voir que Callable prend en charge les génériques.
2. Le futur
Future est le suivant :
public interface Future<V> { // 试图取消对此任务的执行。 boolean cancel(boolean mayInterruptIfRunning) // 如果在任务正常完成前将其取消,则返回 true。 boolean isCancelled() // 如果任务已完成,则返回 true。 boolean isDone() // 如有必要,等待计算完成,然后获取其结果。 V get() throws InterruptedException, ExecutionException; // 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。 V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
Explication : Future est utilisé pour représenter les résultats de calculs asynchrones. Sa classe d'implémentation est FutureTask. Avant d'expliquer FutureTask, examinons d'abord le diagramme de relation entre Callable, Future et FutureTask, comme suit :
Description :
public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); }(02) FutureTask implémente l'interface RunnableFuture. Par conséquent, nous disons également qu’il implémente l’interface Future.
Exemple et analyse du code source (basé sur JDK1.7.0_40)
import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutionException; class MyCallable implements Callable { @Override public Integer call() throws Exception { int sum = 0; // 执行任务 for (int i=0; i<100; i++) sum += i; //return sum; return Integer.valueOf(sum); } } public class CallableTest1 { public static void main(String[] args) throws ExecutionException, InterruptedException{ //创建一个线程池 ExecutorService pool = Executors.newSingleThreadExecutor(); //创建有返回值的任务 Callable c1 = new MyCallable(); //执行任务并获取Future对象 Future f1 = pool.submit(c1); // 输出结果 System.out.println(f1.get()); //关闭线程池 pool.shutdown(); } }Résultat de l'exécution :
Description du résultat :
1. submit()
public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); // 创建一个RunnableFuture对象 RunnableFuture<T> ftask = newTaskFor(task); // 执行“任务ftask” execute(ftask); // 返回“ftask” return ftask; }Explication : submit() crée l'objet RunnableFuture ftask via newTaskFor(task). Son code source est le suivant :
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable); }
2. Le constructeur de FutureTask
public FutureTask(Callable<V> callable) { if (callable == null) throw new NullPointerException(); // callable是一个Callable对象 this.callable = callable; // state记录FutureTask的状态 this.state = NEW; // ensure visibility of callable }
3. Méthode run() de FutureTask
Après que newTaskFor() ait créé un objet ftask, la tâche sera exécutée viaexecute(ftask). À ce stade, ftask est exécuté en tant qu'objet Runnable, et sa méthode run() sera éventuellement appelée ; la méthode run() de ftask est implémentée dans java/util/concurrent/FutureTask.java, et le code source est le suivant. :
public void run() { if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset, null, Thread.currentThread())) return; try { // 将callable对象赋值给c。 Callable<V> c = callable; if (c != null && state == NEW) { V result; boolean ran; try { // 执行Callable的call()方法,并保存结果到result中。 result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } // 如果运行成功,则将result保存 if (ran) set(result); } } finally { runner = null; // 设置“state状态标记” int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } }
Explication : run() exécutera la méthode call() de l'objet Callable, et enfin enregistrera le résultat dans le résultat, et enregistrera le résultat via set(result) . Après avoir appelé la méthode get() de FutureTask, la valeur enregistrée par set(result) est renvoyée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!