当前位置:嗨网首页>书籍在线阅读

36-案例实现

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

案例实现

根据如下步骤实现本案例:

1.创建一个名为 ReportGenerator 的类,并实现泛型为 StringCallable 接口:

public class ReportGenerator implements Callable<String> {

2.声明两个名为 sendertitle 的私有变量。这些变量将会展示报告数据:

private final String sender;
private final String title;

3.实现该类的构造方法,并初始化类中变量:

public ReportGenerator(String sender, String title){
  this.sender=sender;
  this.title=title;
}

4.实现 call() 方法。首先让该线程随机休眠一段时间:

@Override
public String call() throws Exception {
  try {
    Long duration=(long)(Math.random()*10);
    System.out.printf("%s_%s: ReportGenerator: Generating a
                      report during %d seconds\n",this.sender,
                      this.title,duration);
    TimeUnit.SECONDS.sleep(duration);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }

5.用 sender 变量和 title 变量来生成一个 String 类型的报告并返回值:

  String ret=sender+": "+title;
  return ret;
}

6.创建一个名为 ReportRequest 的类,并实现 Runnable 接口。该类将模拟一些报告请求:

public class ReportRequest implements Runnable {

7.声明一个名为 name 的私有 String 型变量,用来存储 ReportRequest的 名称:

private final String name;

8.声明一个名为 service 的私有 CompletionService 型变量。该 Completion- Service 接口的泛型为 String

private final CompletionService<String> service;

9.实现该类的构造方法,并初始化类中变量:

public ReportRequest(String name, CompletionService<String>
                     service){
  this.name=name;
  this.service=service;
}

10.实现 run() 方法。创建3个 ReportGenerator 实例对象并使用 submit() 方法提交给 CompletionService 对象:

@Override
public void run() {
  ReportGenerator reportGenerator=new ReportGenerator(name,
                                                      "Report");
  service.submit(reportGenerator);
}

11.创建一个名为 ReportProcessor 的类,并实现 Runnable 接口。该类用来接收 Report Generator 任务返回的结果:

public class ReportProcessor implements Runnable {

12.声明一个名为 service 的私有 CompletionService 类型变量。 Completion- Service 接口的泛型为 String

private final CompletionService<String> service;

13.声明一个名为 end 的私有 boolean 型变量。添加 volatile 关键字来确保所有线程都可以获取到该变量的真实值:

private volatile boolean end;

14.实现该类的构造方法,并初始化类中变量:

public ReportProcessor (CompletionService<String> service){
  this.service=service;
  end=false;
}

15.实现 run() 方法。当变量 endfalse 的时候,调用 CompletionService 接口的 poll() 方法来获取下一个任务已执行完成的 Future 对象:

@Override
public void run() {
  while (!end){
    try {
      Future<String> result=service.poll(20, TimeUnit.SECONDS);

16.调用 Futureget() 方法获取任务的返回结果,并在控制台打印输出:

      if (result!=null) {
        String report=result.get();
        System.out.printf("ReportReceiver: Report Received: %s\n",
                          report);
      }
    } catch (InterruptedException | ExecutionException e) {
      e.printStackTrace();
    }
  }
  System.out.printf("ReportSender: End\n");
}

17.实现 stopProcessing() 方法并覆盖 end 变量的值:

public void stopProcessing() {
  this.end = true;
}

18.至此,我们可以开始实现应用程序的入口,创建包含 main() 方法的 Main 类:

public class Main {
  public static void main(String[] args) {

19.用 Executors 类的 newCachedThreadPool() 方法来创建 ThreadPoolExecutor 实例对象:

ExecutorService executor=Executors.newCachedThreadPool();

20.创建 CompletionService 对象,传入之前创建的 executor 作为构造参数:

CompletionService<String> service=new
                           ExecutorCompletionService<>(executor);

21.创建两个 ReportRequest 实例对象,并创建线程执行它们:

ReportRequest faceRequest=new ReportRequest("Face", service);
ReportRequest onlineRequest=new ReportRequest("Online", service);
Thread faceThread=new Thread(faceRequest);
Thread onlineThread=new Thread(onlineRequest);

22.创建一个 ReportProcessor 实例对象,并创建线程执行它们:

ReportProcessor processor=new ReportProcessor(service);
Thread senderThread=new Thread(processor);

23.启动以上3个线程:

System.out.printf("Main: Starting the Threads\n");
faceThread.start();
onlineThread.start();
senderThread.start();

24.等待 ReportRequest 线程执行完成:

try {
  System.out.printf("Main: Waiting for the report generators.\n");
  faceThread.join();
  onlineThread.join();
} catch (InterruptedException e) {
  e.printStackTrace();
}

25.调用 shutdown() 方法结束执行器,并用 awaitTermination() 方法等待剩余任务执行完毕:

System.out.printf("Main: Shutting down the executor.\n");
executor.shutdown();
try {
  executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
  e.printStackTrace();
}

26.结束 ReportSender 对象的执行,设置 end 变量值为 true

processor.stopProcessing();
System.out.println("Main: Ends");