使用AsyncHttpClient和Quartz Job运行的线程

时间:2012-10-15 20:49:33

标签: java multithreading http quartz-scheduler jvisualvm

这是一个简单的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 ......等等。 enter image description here

编辑

我能够验证它是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();

一切按预期工作。

1 个答案:

答案 0 :(得分:2)

您必须关闭此处创建的每个AsyncHttpClient实例:

Future<Response> r = new AsyncHttpClient().prepareGet(
                "http://google.com").execute();

使用close()方法。每个AsyncHttpClient实例都会创建一些必须清理的资源(如线程)。

但是,由于AsyncHttpClient是线程安全的,因此更好的方法是只创建一个AsyncHttpClient的全局实例,并在应用程序的整个生命周期内以及从多个线程重用它。

最后,由于您基本上发送了一些请求并同步等待(阻止)响应,为什么不使用标准URLConnection(如您的示例中)或HttpClient?当您不想等待同步响应时,AsyncHttpClient很棒,例如当你想同时发起数百个HTTP请求而不产生数百个线程时。然后AsyncHttpClient将在响应出现时调用您的回调代码。