这是一个简单的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分钟后侵占就会明显。前24,比27,30 ......等等。
编辑:
我能够验证它是AsyncHttpClient和Quartz的组合,就像我用标准请求交换makeRequest
方法一样:
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();
一切按预期工作。
答案 0 :(得分:2)
您必须关闭此处创建的每个AsyncHttpClient
实例:
Future<Response> r = new AsyncHttpClient().prepareGet(
"http://google.com").execute();
使用close()
方法。每个AsyncHttpClient
实例都会创建一些必须清理的资源(如线程)。
但是,由于AsyncHttpClient
是线程安全的,因此更好的方法是只创建一个AsyncHttpClient
的全局实例,并在应用程序的整个生命周期内以及从多个线程重用它。
最后,由于您基本上发送了一些请求并同步等待(阻止)响应,为什么不使用标准URLConnection
(如您的示例中)或HttpClient?当您不想等待同步响应时,AsyncHttpClient
很棒,例如当你想同时发起数百个HTTP请求而不产生数百个线程时。然后AsyncHttpClient
将在响应出现时调用您的回调代码。