2014-01-13 130 views
0

我一直想測試異步方法。我無法理解 - 對於所調用的每個異步,都是分配給它的新線程,或者它們是否在一個線程中進入隊列。異步不起作用2.1

所以想測試它,但得到了奇怪的結果。 代碼:

// block request and current thread 
    public static Result syncFreeze() { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(
       System.in)); 
     String a = null; 
     try { 
      System.out.println("sync freeze " + Thread.activeCount() 
        + " threads running with active thread name " 
        + Thread.currentThread().getName()); 
      a = reader.readLine(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return ok(a); 
    } 

    // block request but should keep thread open 
    public static Result asyncFreeze() { 
     Promise<String> promiseOfString = play.libs.Akka.future(new Reader()); 
     return async(promiseOfString.map(new Function<String, Result>() { 
      public Result apply(String s) { 
       return ok(s); 
      } 
     })); 
    } 

    static class Reader implements Callable<String> { 
     public String call() { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(
        System.in)); 
      String a = null; 
      System.out.println("Async freeze " + Thread.activeCount() 
        + " threads running with active thread name " 
        + Thread.currentThread().getName()); 
      try { 
       a = reader.readLine(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      return a; 
     } 
    } 

我認爲,如果asyncFreeze被稱爲,這永遠都不會阻塞線程處理HTTP請求。但它的執行方式與syncFreeze()不同。對於這兩種方法, - 曾經調用過8次,沒有其他頁面可以加載 - 顯示所有服務請求的線程都被阻塞。但是這對我來說沒有任何意義 - 這應該是async()方法的重點。它應該允許主線程處理請求繼續。全都談到了 here

我在做什麼錯?

非常感謝

(建議編輯) - 我如何測試它:

我只是重新加載指向同步和異步方法的瀏覽器。對於每次調用,該方法都會鎖定,直到從終端輸入 - 。起初,我不打開它。我只是繼續重新加載調用sync()或async(),而在另一個瀏覽器窗口中,我嘗試加載索引()頁面。最後(實際上在8次調用sync()/ async()之後)所有線程都被阻塞,並且index()不加載 - 直到我通過在終端窗口上按Enter解鎖線程。

+0

你能否也請提供你如何測試? – arbuzz

+0

@arbuzz感謝您的建議 - 請參閱編輯問題。 –

回答

0

這應該解釋所有你想知道的事情:http://www.playframework.com/documentation/2.2.x/ThreadPools

不久,這不是一個線程每個請求的模式。 Play使用Akka,這是一個反應式編程原則的實現。簡單的說 - 有一個線程池(或更多線程池),並且一旦該池的所有線程都忙碌,則不會執行任何其他操作。如果您有阻止代碼,那麼在文章中解釋如何處理它。

+0

謝謝 - 但我仍然有麻煩 - 一些例子是在斯卡拉,我不是很有信心 - 我主要在模板中使用它。我仍然不知道如何處理阻止請求。我怎麼能發送請求到另一個線程/甚至線程池,並提取結果,當它完成?所有這些都不會阻塞默認線程池中的請求處理程序?您是否能夠發佈代碼段 - 非常感謝您的幫助。 –

+0

我很遺憾地說,但要了解這些東西,你必須研究一下。不要考慮線程。有演員。嘗試閱讀本文:http://www.playframework.com/documentation/2.2.x/JavaAkka –

+0

雷達布蘭斯基感謝無論如何 - 這是我最接近的每一個戈特解決/理解多線程播放。我會對此有一個很好的研究,希望能夠弄清楚。 –