1. 程式人生 > 實用技巧 >java.util.concurrent.Executor

java.util.concurrent.Executor

簡介:

An object that executes submitted {@link Runnable} tasks.

這個介面提供了一種將任務提交與每個任務的執行機制分離的方法。通常使用{@code Executor}而不是顯式建立執行緒。

例如:

不是為每一個任務排程

new Thread(new(RunnableTask())).start()

而是

Executor executor =  ... ;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());

注意:Executor介面並不嚴格要求執行是非同步的。

在最簡單的情況下,執行者可以立即在呼叫者的執行緒中執行提交的任務:

class DirectExecutor implements Executor {
       public void execute(Runnable r) {
              r.run();
       }
}    

更典型地,任務在呼叫者執行緒之外的某個執行緒中執行。

例如:下面的執行程式為每個任務生成一個新執行緒:

public class ThreadPerTaskExecutor implements Executor {
    public void execute(Runnable r) {
        
new Thread(r).start(); } }

許多Executor實現對計劃任務的方式和時間施加了某種限制。

下面的執行程式將任務提交序列化到第二個執行程式,演示了一個複合執行器(a composite executor)。

import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.Executor;




public class SerialExecutor implements Executor {
    final Queue<Runnable> tasks = new
ArrayDeque<Runnable>(); final Executor executor; Runnable active; SerialExecutor(Executor executor) { this.executor = executor; } public synchronized void execute(final Runnable r) { tasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (active == null) { System.out.println("active == null!"); scheduleNext(); } } protected synchronized void scheduleNext() { if ((active = tasks.poll()) != null) { executor.execute(active); } } }

綜合演示:

import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.Executor;

class DirectExecutor implements Executor {
    public void execute(Runnable r) {
        r.run();
    }
}


class ThreadPerTaskExecutor implements Executor {
    public void execute(Runnable r) {
        new Thread(r).start();
    }
}


public class SerialExecutor implements Executor {
    final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
    final Executor executor;
    Runnable active;

    SerialExecutor(Executor executor) {
        this.executor = executor;
    }

    public synchronized void execute(final Runnable r) {
        tasks.offer(new Runnable() {
            public void run() {
                try {
                    r.run();
                } finally {
                    scheduleNext();
                }
            }
        });

        if (active == null) {
            System.out.println("active == null!");
            scheduleNext();
        }
    }

    protected synchronized void scheduleNext() {
        if ((active = tasks.poll()) != null) {
            executor.execute(active);
        }
    }
}


class SerialExecutorMain {
    public static void main(String[] args) {
        SerialExecutor serialExecutor = new SerialExecutor(new ThreadPerTaskExecutor());
        /**or**/
        //SerialExecutor serialExecutor = new SerialExecutor(new DirectExecutor());
        for (int i = 0; i < 100; i++) {
            serialExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("Hello!");
                }
            });
        }
    }
}