Executor, ExecutorService, Executor - 1

"Chào, Amigo!"

"Không có gì là hoàn hảo khi nó được tạo ra lần đầu tiên. Điều này cũng đúng với các luồng. Theo thời gian, những người tạo ra Java đã bị thuyết phục về những thiếu sót của giao diện Runnable. Nó không hỗ trợ đưa ra các ngoại lệ và không thể tìm ra nguyên nhân kết quả của việc thực hiện nhiệm vụ…”

"Giao diện Runnable phù hợp hơn cho các nhiệm vụ lớn độc lập hơn là các nhiệm vụ nhỏ mà bạn muốn chạy hàng chục nhiệm vụ cùng một lúc và sau đó thu thập kết quả của chúng."

"Đó là lý do tại sao giao diện Callable được phát minh. Nó phù hợp hơn nhiều để thực thi song song các tác vụ nhỏ so với RunnableThread, một phần vì nó là giao diện chung."

"Đây là một triển khai điển hình của giao diện:"

Ví dụ
class ReverseString implements Callable<String>
{
 String str;

 ReverseString(String str)
 {
  this.str = str;
 }

 public String call() throws Exception
 {
  StringBuilder builder = new StringBuilder(str);
  builder.reverse();
  return builder.toString();
 }
}

"Không giống như Runnable , ở đây chúng ta cần ghi đè phương thức gọi, phương thức này trả về kết quả thuộc loại được chỉ định bởi đối số loại. Cách tiếp cận này thuận tiện hơn nhiều so với phương thức chạy của giao diện Runnable, phương thức này trả về khoảng trống. Đôi khi các nhà phát triển phải nghĩ ra nhiều cách giải quyết khác nhau để có được kết quả của chuỗi."

"Tôi hiểu rồi."

"Và bây giờ hãy xem cách Callable có thể hoạt động cùng với ThreadPoolExecutor:

"Đầu tiên, phương thức gửi của lớp ThreadPoolExecutor trả về một đối tượng Tương lai được tham số hóa. Bạn có thể sử dụng đối tượng này để tìm hiểu xem một tác vụ đã hoàn thành hay chưa và để nhận kết quả."

"Đây là cách nó hoạt động:"

Ví dụ
// 1. Create a ThreadPoolExecutor
ExecutorService service = Executors.newFixedThreadPool(5);

// 2. Add a task to it
Future<String> task = service.submit(new ReverseString("Amigo"));

// 3. Wait until the task is done
while(!task.isDone())
{
 Thread.sleep(1);
}

// 4. Try to get the result
//We will get either the result, or an exception if one occurred while the task was being executed
try
{
 System.out.println("Full string : " + task.get());
}
catch (Exception ie)
{
 ie.printStackTrace(System.err);
}
  
// 5. Stop the ThreadPool.
service.shutdown();

"Xa xa! Tôi đặc biệt thích lớp Tương lai. Nó có những phương pháp nào?"

"Đây là những điều thú vị nhất:"

Phương pháp Sự miêu tả
boolean cancel(boolean mayInterrupt);
Dừng nhiệm vụ.
boolean isCancelled();
Trả về true nếu tác vụ bị dừng.
boolean isDone();
Trả về true nếu tác vụ được thực hiện xong.
V get() throws InterruptedException, ExecutionException;
Trả về kết quả của phương thức gọi hoặc đưa ra một ngoại lệ nếu xảy ra.

"Tuyệt! Vì vậy, bạn cũng có thể dừng các nhiệm vụ."

"Đừng dựa vào điều này quá nhiều—không phải chuỗi nào cũng có thể dừng. Nhưng nếu một tác vụ vẫn đang trong hàng đợi, thì điều này sẽ hoạt động tốt."

"Tôi thích cách tiếp cận này. Nó thuận tiện hơn nhiều so với việc tự mình tạo ra các chủ đề và sau đó cố gắng rút ra kết quả từ chúng."

"Tuyệt. Đó là nơi chúng ta sẽ kết thúc ngày hôm nay."