Java 线程通过AsyncHttpClient和Quartz作业疯狂运行
下面是一个简单的Quartz调度程序,它应该每分钟运行一次作业;作业本身使用Sonatype发出HTTP请求。使用Java 线程通过AsyncHttpClient和Quartz作业疯狂运行,java,multithreading,http,quartz-scheduler,jvisualvm,Java,Multithreading,Http,Quartz Scheduler,Jvisualvm,下面是一个简单的Quartz调度程序,它应该每分钟运行一次作业;作业本身使用Sonatype发出HTTP请求。使用jvisualvm,我能够检测到线程的繁殖和从不关闭,例如,它们被困在等待中。这让我相信,要么A)我误解了石英如何与这个特定的设置一起工作,要么B)其他的东西出了问题。可能是:)调度程序: public class QuartzAsyncHttpThreadTest { /* TEST */ @SuppressWarnings("rawtypes") pri
jvisualvm
,我能够检测到线程的繁殖和从不关闭,例如,它们被困在等待中。这让我相信,要么A)我误解了石英如何与这个特定的设置一起工作,要么B)其他的东西出了问题。可能是:)调度程序:
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();
}
}
}
所有工作正常。您必须关闭在此处创建的每个
AsyncHttpClient
实例:
Future<Response> r = new AsyncHttpClient().prepareGet(
"http://google.com").execute();
Future r=new AsyncHttpClient().prepareGet(
"http://google.comexecute();
使用方法。AsyncHttpClient
的每个实例都会创建一些必须清理的资源(如线程)
但是,由于AsyncHttpClient
是线程安全的,因此更好的方法是只创建一个AsyncHttpClient
的全局实例,并在应用程序的整个生命周期和多个线程中重用它
最后,既然您基本上发送一些请求并同步(阻塞)等待响应,为什么不使用标准的
URLConnection
(如您的示例中所示)或AsyncHttpClient
在您不想同步等待响应时非常有用,例如,当您想同时启动数百个HTTP请求而不产生数百个线程时AsyncHttpClient
将在响应出现时调用回调代码。您是否可以对卡住的线程进行线程转储(例如,使用jvisualvm
)?它们是否挂在r.get()
上?是否显示过请求状态:?如果你仍然同步地等待响应,为什么还要使用异步客户端呢?从文档上看,它说这是使用异步客户端的阻塞方式,不是吗?所以我觉得这不重要。我确实看到“请求状态”被记录。我可以转储线程,但每次都会出现图中所示的AsyncHttpClient Reaper线程。
Future<Response> r = new AsyncHttpClient().prepareGet(
"http://google.com").execute();