TimerTask挂起

时间:2016-02-09 15:37:06

标签: java multithreading timer

我试图通过Java中的TimerTask功能从main()启动一个句点任务,并且run()任务挂起。 Timer之后的代码是REPL。代码如下所示:

def view_func(request):
    form = PortalNoteForm(request.POST or None)
    if form.is_valid():
        options = form.cleaned_data['public_options']
        # now you have options so use it

该任务尝试建立多个URL连接并打印出每个URL的响应。在实践中发生的事情是“从......检索数据”消息出现一次,然后任务似乎挂起。如果我使用REPL,在StdIn上键入命令,则stdout中会出现“连接超时”错误。

因此,TimerTask似乎与某种方式的REPL(在readline上阻塞)相冲突。这是怎么回事?

2 个答案:

答案 0 :(得分:0)

java.util.TimerTask只有线程来运行任务。如果一个任务继续运行,其他任务必须等待util完成。 您可以将其替换为java.util.concurrent.ScheduledExecutorService,它可以启动更多线程来运行任务...

我猜你尝试连接的网址需要一些"输入",所以它等待额外的数据...... 尝试修改源代码并为其提供一些数据。例如:

    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setConnectTimeout(5000);//not required
    con.setDoOutput(true);
    con.setDoInput(true);
    OutputStream out = con.getOutputStream();
    out.write("&param1=a&param2=b".getBytes());
    out.close();
    sb = readStream( con.getInputStream() );

答案 1 :(得分:0)

我最终发现了这个问题。 HttpURLConnection openConnection方法实现在一个名为streamHandlerLock的内部对象上进行同步,该对象由一堆不同的内部Java库共享,包括缓冲的读取库。

这基本上意味着您不能在多个并发线程中使用java.net或java.io来使用任何基于流的IO。

在我的情况下,发生的事情是REPL在BufferedReader.readLine()上阻塞,因此streamHandlerLock被冻结。因此,当openConnection执行时,它会对此对象造成死锁。

(我可以在这里谈谈James Gosling的编码技巧,他设计并编写了这个borked up系统,并在源代码上签了名,或者我可以说一下Sun Oak团队的彻底失败当Java在16年前的2000年成为主流时重写这个垃圾,但我想我会把它留给读者的想象力,我会说些什么。)