Java执行器模式是一种设计模式,它可以帮助程序员在Java应用程序中实现命令行界面。它使用一个特殊的对象来处理用户输入,并将其转换为有意义的操作。这样,用户可以通过命令行界面来执行特定的任务,而无需了解底层代码。
Java执行器模式的核心是一个特殊的对象,即Executor对象。Executor对象可以处理用户的命令(如“run”、“stop”、“restart”等)并将其映射到相应的方法。例如:当用户在命令行中输入“run”时,Executor对象会将该命令映射到相应的run()方法上。
public class Executor { public void execute(String command) { if (command.equals("run")) { run(); } else if (command.equals("stop")) { stop(); } else if (command.equals("restart")) { restart(); } } private void run() { // do something } private void stop() { // do something } private void restart() { // do something } }
框架提供了一种将任务提交与任务执行分离的方法。
java.util.concurrent包中的Executor接口是执行器框架的基础。
它是一个只有一个方法的接口,如图所示:
public interface Executor { void execute (Runnable command); }
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class RunnableTask implements Runnable { private int taskId; private int loopCounter; public RunnableTask(int taskId, int loopCounter) { this.taskId = taskId; this.loopCounter = loopCounter; } public void run() { for (int i = 1; i <= loopCounter; i++) { try { System.out.println("Task #" + this.taskId + " - Iteration #" + i); Thread.sleep(1000); } catch (Exception e) { System.out.println("Task #" + this.taskId + " has been interrupted."); break; } } } } public class Main { public static void main(String[] args) { final int THREAD_COUNT = 3; final int LOOP_COUNT = 3; final int TASK_COUNT = 5; // Get an executor with three threads in its thread pool ExecutorService exec = Executors.newFixedThreadPool(THREAD_COUNT); // Create five tasks and submit them to the executor for (int i = 1; i <= TASK_COUNT; i++) { RunnableTask task = new RunnableTask(i, LOOP_COUNT); exec.submit(task); } exec.shutdown(); } }
上面的代码生成以下结果。
要在任务完成时获取任务的结果,请使用Callable接口的实例。
类型参数V是任务的结果的类型。
Callable接口有一个call()方法。它可以返回任何类型的值。
它允许你抛出异常。它声明如下:
public interface Callable<V> { V call() throws Exception; }
import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; class CallableTask implements Callable<Integer> { private int taskId; public CallableTask(int taskId) { this.taskId = taskId; } public Integer call() throws InterruptedException { int total = taskId; try { System.out.println("Task #" + this.taskId); Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Task #" + this.taskId + " has been interupted."); throw e; } total+=taskId; return total; } } public class Main { public static void main(String[] args) throws Exception { // Get an executor with three threads in its thread pool ExecutorService exec = Executors.newFixedThreadPool(3); CallableTask task = new CallableTask(1); // Submit the callable task to executor Future<Integer> submittedTask = exec.submit(task); Integer result = submittedTask.get(); System.out.println("Task"s total sleep time: " + result + " seconds"); exec.shutdown(); } }
上面的代码生成以下结果。
执行器框架允许您计划将来运行的任务。
import java.time.LocalDateTime; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; class ScheduledTask implements Runnable { private int taskId; public ScheduledTask(int taskId) { this.taskId = taskId; } public void run() { LocalDateTime currentDateTime = LocalDateTime.now(); System.out.println("Task #" + this.taskId + " ran at " + currentDateTime); } } public class Main { public static void main(String[] args) { // Get an executor with 3 threads ScheduledExecutorService sexec = Executors.newScheduledThreadPool(3); ScheduledTask task1 = new ScheduledTask(1); ScheduledTask task2 = new ScheduledTask(2); // Task #1 will run after 2 seconds sexec.schedule(task1, 2, TimeUnit.SECONDS); // Task #2 runs after 5 seconds delay and keep running every 10 seconds sexec.scheduleAtFixedRate(task2, 5, 10, TimeUnit.SECONDS); try { TimeUnit.SECONDS.sleep(60); } catch (InterruptedException e) { e.printStackTrace(); } sexec.shutdown(); } }
上面的代码生成以下结果。
执行器框架在任务执行期间处理任何未捕获异常的事件。
如果使用Executor对象的execute()方法执行Runnable任务,任何未捕获的运行时异常将停止任务执行,并且异常堆栈跟踪将打印在控制台上。
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main { public static void main(String[] args) { Runnable badTask = () -> { throw new RuntimeException( "Throwing exception from task execution..."); }; ExecutorService exec = Executors.newSingleThreadExecutor(); exec.execute(badTask); exec.shutdown(); } }
上面的代码生成以下结果。
以下代码显示了如何在Callable任务中处理异常。
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Main { public static void main(String[] args) { Callable<Object> badTask = () -> { throw new RuntimeException( "Throwing exception from task execution..."); }; ExecutorService exec = Executors.newSingleThreadExecutor(); Future submittedTask = exec.submit(badTask); try { Object result = submittedTask.get(); } catch (ExecutionException e) { System.out.println(e.getMessage()); System.out.println(e.getCause().getMessage()); } catch (InterruptedException e) { e.printStackTrace(); } exec.shutdown(); } }
要将提交的任务的结果提供给执行程序,请使用执行程序的完成服务。
它由CompletionService接口的一个实例表示。
import java.util.concurrent.Callable; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; class MyResult { private int taskId; private int result; public MyResult(int taskId, int result) { this.taskId = taskId; this.result = result; } public int getTaskId() { return taskId; } public int getResult() { return result; } public String toString() { return "Task Name: Task #" + taskId + ", Task Result:" + result + " seconds"; } } class SleepingTask implements Callable<MyResult> { private int taskId; private int loopCounter; public SleepingTask(int taskId, int loopCounter) { this.taskId = taskId; this.loopCounter = loopCounter; } public MyResult call() throws InterruptedException { int totalSleepTime = 0; for (int i = 1; i <= loopCounter; i++) { try { System.out.println("Task #" + this.taskId + " - Iteration #" + i); Thread.sleep(1000); totalSleepTime = totalSleepTime + 1000; } catch (InterruptedException e) { System.out.println("Task #" + this.taskId + " has been interupted."); throw e; } } return new MyResult(taskId, totalSleepTime); } } public class Main { public static void main(String[] args) throws Exception { // Get an executor with three threads in its thread pool ExecutorService exec = Executors.newFixedThreadPool(3); // Completed task returns an object of the TaskResult class ExecutorCompletionService<MyResult> completionService = new ExecutorCompletionService<>( exec); for (int i = 1; i <= 5; i++) { SleepingTask task = new SleepingTask(i, 3); completionService.submit(task); } for (int i = 1; i <= 5; i++) { Future<MyResult> completedTask = completionService.take(); MyResult result = completedTask.get(); System.out.println("Completed a task - " + result); } exec.shutdown(); } }
上面的代码生成以下结果。
Java网络教程 -Java网络UDP多播Java使用MulticastSocket类来创建UDP多播套接字,以接收发送到多播IP地址的数据包。组播套接字基...
JavaFX教程 -JavaFX颜色在JavaFX中,我们可以对对象应用颜色(Paint)。在JavaFX中,所有形状都可以填充简单的颜色和渐变颜色。R...
JavaFX教程 -JavaFX多边形折线多边形import javafx.application.Application;import javafx.scene.Group;import javafx.scene.Sc...
JavaFX教程 -JavaFX 单选按钮单选按钮通常组合在一起以允许用户进行单选,即用户只能在单选按钮列表中选择一个项目。例如,当选...