这是一个简单的 Quartz 调度程序,它应该每分钟运行一次;作业本身使用 Sonatype Async Http Client 发出 HTTP 请求。使用jvisualvm
,我能够检测线程的产生和永不关闭,例如他们陷入了等待。这让我相信要么 A) 我误解了 Quartz 如何在这个特定的设置下工作,要么 B) 其他地方出了问题。可能是 A :) 调度程序:
public class QuartzAsyncHttpThreadTest {
/* TEST */
@SuppressWarnings("rawtypes")
private static Class jobToRun = AsyncHttpRequestJob.class;
private static String cron = "0 0/1 * * * ?";
/* TEST */
public static void main(String[] args) throws SchedulerException {
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
start(scheduler, jobToRun.getName(), jobToRun);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void start(Scheduler scheduler, String name, Class job)
throws SchedulerException {
JobKey monitorKey = new JobKey(name + "_job", "jobs");
JobDetail detail = JobBuilder.newJob(job).withIdentity(monitorKey)
.build();
Trigger cronDef = TriggerBuilder.newTrigger()
.withIdentity(name + "_trigger", "triggers")
.withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
scheduler.scheduleJob(detail, cronDef);
}
}
工作:
public class AsyncHttpRequestJob implements Job {
public AsyncHttpRequestJob() {
}
public void execute(JobExecutionContext context)
throws JobExecutionException {
System.out.println("Go..");
makeRequest();
}
public static void makeRequest() {
try {
Future<Response> r = new AsyncHttpClient().prepareGet(
"http://google.com").execute();
Response response = r.get();
System.out.println("Request status: " + response.getStatusCode()); // 301
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
其实没什么。如果我分析实时线程,则 2 分钟后就会明显受到侵 eclipse 。先是 24,然后是 27、30...等等。
编辑:
当我用标准请求替换 makeRequest
方法时,我能够验证它是 AsyncHttpClient 和 Quartz 的组合:
URL conn = new URL("http://google.com");
URLConnection httpR = conn.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
httpR.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
一切都按预期进行。
最佳答案
您必须关闭此处创建的每个 AsyncHttpClient
实例:
Future<Response> r = new AsyncHttpClient().prepareGet(
"http://google.com").execute();
使用 close()
方法。 AsyncHttpClient
的每个实例都会创建一些必须清理的资源(例如线程)。
但是,由于 AsyncHttpClient
是线程安全的,因此更好的方法是仅创建一个 AsyncHttpClient
的全局实例,并在应用程序的整个生命周期中重用它。多线程。
最后,由于您基本上发送一些请求并同步(阻塞)等待响应,为什么不使用标准 URLConnection
(如您的示例中所示)或 HttpClient ?当您不想同步等待响应时,AsyncHttpClient
非常有用,例如当您想要同时发起数百个 HTTP 请求而不生成数百个线程时。然后,AsyncHttpClient
将在响应出现时调用您的回调代码。
关于java - 使用 AsyncHttpClient 和 Quartz Job 疯狂运行的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12903761/