Chinaunix首页 | 论坛 | 博客
  • 博客访问: 530464
  • 博文数量: 135
  • 博客积分: 3568
  • 博客等级: 中校
  • 技术积分: 1942
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-19 17:52
文章分类

全部博文(135)

文章存档

2012年(29)

2011年(41)

2010年(26)

2009年(12)

2008年(9)

2007年(12)

2006年(6)

分类: Java

2011-11-23 20:22:37

运行结果:
  1. 21:31:44 - 111 started.
  2. 21:31:47 - 111 ended.
  3. 21:31:47 - 222 started.
  4. 21:31:53 - 222 is timeout and is stopped.

源代码:

  1. /**
  2.  * 问题1:如果第三方提供了一个Runable类,我作为平台为其单独创建了一个Thread对象来运行。
  3.  * 但是由于计费要监视其CPU使用时间,超过一定时间后要收费,费用为0时要终止该线程。
  4.  *
  5.  * 对应方法:如果使用java.lang.management.ThreadMXBean,则只能监测,不能终止,
  6.  * 这时需要提供一个终止指定线程的服务接口方可。
  7.  *
  8.  * 问题2:如果第三方提供了一个方法,但该方法是直接在当前线程中被调用,
  9.  * 我也要对其监测运行时间,并终止可能的死循环代码。
  10.  *         如何确定某个方法的执行时间有多长?一般大家的想法可能都是:
  11.  *

  12.  * long startTime = System.currentTimeMillis();
  13.  * ...// 执行某些业务代码
  14.  * long endTime = System.currentTimeMillis();
  15.  * long execDuration = endTime - startTime;
  16.  *
  17.  * 但是,这样的话,只能够被动检测——即,如果这些业务代码是第三方所提供,
  18.  * 其内部执行了一个死循环,则永远都无法检测其执行时间了,只能被强制stop。
  19.  * 若想能够主动在超时时就终止,只能将该方法的代码放到单独一个线程中执行。
  20.  * 下面的代码就说明了该例子。其中主要用到了Thread#join(long)方法。
  21.  *
  22.  * 注意:该例子只是监测该方法总共执行了多少时间(可能代码本身执行完毕花费了10秒,
  23.  * 而代码内部等待锁、IO信号、休眠等就花费了9秒),如果要计算该方法代码本身真正执行
  24.  * 使用了多长时间,则仍然需要使用java.lang.management.ThreadMXBean#getThreadCpuTime(long)方法。
  25.  *
  26.  * @author btpka3@163.com
  27.  */
  28. package me.test.join;

  29. import java.text.SimpleDateFormat;
  30. import java.util.Calendar;

  31. public class Main {
  32.     private static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

  33.     public static void main(String[] args) {
  34.         int timeLimit = 5; // 预计TaskA执行不得超过5秒。

  35.         // CASE 1:TaskA的执行时间没有超时。
  36.         check(new TaskA("111", 3), timeLimit);

  37.         // CASE 2:TaskA的执行时间超时,被强制终止。
  38.         check(new TaskA("222", 7), timeLimit);
  39.     }

  40.     @SuppressWarnings("deprecation")
  41.     public static void check(TaskA taskA, int timeLimit) {
  42.         Thread subThread = new Thread(taskA);
  43.         subThread.start(); // 启动子线程
  44.         long startTime = System.currentTimeMillis();
  45.         long endTime = System.currentTimeMillis();
  46.         boolean timeout = endTime - startTime > timeLimit * 1000;

  47.         try {
  48.             // 如果子线程未运行完毕,且未超时,则继续等待子线程。
  49.             while (subThread.isAlive() && !timeout) {
  50.                 subThread.join(1000);

  51.                 endTime = System.currentTimeMillis();
  52.                 timeout = endTime - startTime > timeLimit * 1000;
  53.             }
  54.         } catch (InterruptedException e) {
  55.             e.printStackTrace();
  56.         }

  57.         if (timeout) {
  58.             // 虽然该方法不推荐,但是对陷入死循环的线程也只能使用此方法来结束线程了。
  59.             subThread.stop();
  60.             String now = sdf.format(Calendar.getInstance().getTime());
  61.             System.out.println(now + " - " + taskA.name
  62.                     + " is timeout and is stopped.");
  63.         }
  64.     }

  65.     public static class TaskA implements Runnable {
  66.         private String name = "";
  67.         private int count = 0;

  68.         public TaskA(String name, int count) {
  69.             this.name = name;
  70.             this.count = count;
  71.         }

  72.         public void run() {

  73.             // 开始日志
  74.             String now = sdf.format(Calendar.getInstance().getTime());
  75.             System.out.println(now + " - " + name + " started.");
  76.             // 模拟业务操作
  77.             try {
  78.                 Thread.sleep(1000 * count);
  79.             } catch (InterruptedException e) {
  80.                 now = sdf.format(Calendar.getInstance().getTime());
  81.                 System.out.println(now + " - " + name + " is interrupted.");
  82.             }
  83.             // 结束日志
  84.             now = sdf.format(Calendar.getInstance().getTime());
  85.             System.out.println(now + " - " + name + " ended.");

  86.         }
  87.     }
  88. }
阅读(1656) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~