java - 使用 AsyncHttpClient 和 Quartz Job 疯狂运行的线程

标签 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 分钟后就会明显受到侵 eclipse 。先是 24,然后是 27、30...等等。 enter image description here

编辑:

当我用标准请求替换 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/

相关文章:

Java 8 将多个可选参数映射到一个函数中

java - AppCompatActivity 未实现 LifecycleOwner

python - httplib 与 urllib2 和 cookies

android - 使用 HTTP post 将文件上传到服务器时出现 "Missing file"错误

node.js - 在 multer nodejs 中跟踪文件上传的进度

java - 使用字符串选项优化 if-else/switch-case

java - 客户端-服务器套接字

java - CPU和线程之间有什么关系吗?

c++ - 使用 std::chrono::steady_clock 对线程/异步中的代码进行基准测试

c# - 使用现有对象而不是创建特定的锁定对象安全吗?