java ee打印功能_Java EE:异步构造和功能
java ee打印功能
介紹
Java EE具有許多API和構造以支持異步執行。 從可伸縮性和性能的角度來看,這是至關重要的。
讓我們假設2個模塊相互交互。 當模塊A (發送方)以同步方式向模塊B (接收方)發送消息時,通信將在單個線程的上下文中進行,即,從模塊A發起通信的線程將被阻塞,直到模塊B作出響應為止。
這是一個通用的聲明,但可以擴展到一個簡單的Java方法相互交融的背景下-在這種情況下,從了methodA到的methodB 同步調用將在同一個 線程執行這將被阻塞,直到的methodB返回或拋出一個異常。
為什么在基于Java EE的應用程序中需要異步行為?
我們可以進一步將這一點推算到Java EE領域-服務器之間的通信,例如Web層和EJB層(Servlet和EJB)之間的通信,或者是典型的客戶端服務器交互-瀏覽器與RESTful端點,Servlet等的交互-服務器響應客戶端請求的線程始終阻塞,直到服務器組件響應。
異步執行在這里發揮作用-如果可以釋放/暫停處理客戶端請求的服務器線程 ,并且在單獨的線程中執行實際的業務邏輯(與原始線程不同),則可以極大地提高性能和可伸縮性。 ! 例如,如果分配給偵聽客戶端請求的HTTP偵聽器線程立即釋放,則可以自由地處理來自其他客戶端的請求,并且可以在單獨的容器線程中執行業務邏輯,然后該容器線程可以通過適當的方法(例如, java.util.concurrent.Future對象或通過客戶端注冊的回調處理程序 。 從最終用戶的角度考慮– 響應非常重要!
深入研究:Java EE中的異步構造和API
讓我們看一下Java EE中的一些異步相關功能(API)。 這不是一個詳盡的列表,但是應該是一個很好的起點。
不同的Java EE規范具有促進異步功能的典型方式和API。 讓我們探索以下Java EE規范
- JAX-RS 2.0(Java EE 7)
- Websocket 1.0(Java EE 7)
- 并發實用工具1.0(Java EE 7)
- EJB 3.1(Java EE 6)
- Servlet 3.0(Java EE 6)
注意 :下面提供的代碼為摘要形式(出于明顯的原因)。 完整樣本可在此處訪問 。
JAX-RS 2.0
請求的異步處理是JAX-RS 2.0版 (Java EE 7中的新增功能 )的一項新功能 。 為了使用JAX-RS API執行aysnc請求,需要在JAX-RS資源方法本身中注入對javax.ws.rs.container.AsyncResponse接口的引用。 此參數將請求執行置于異步模式,然后該方法繼續執行。 業務邏輯執行完成后,需要從單獨的線程中調用AsynResponse對象上的resume方法。 可以利用Java EE并發實用程序功能(稍后討論),例如javax.enterprise.concurrent.ManagedExecutorService ,以將業務邏輯封裝為Runnable對象,并將其提交給容器的執行者服務,其余的工作由該服務執行。 無需自己產生不受管理的隔離線程。
@Path("/{id}")@GET@Produces("application/xml")public void asyncMethod(@Suspended AsyncResponse resp, @PathParam("id") String input) {System.out.println("Entered MyAsyncRESTResource/asyncMethod() executing in thread: "+ Thread.currentThread().getName());mes.execute(() -> {System.out.println("Entered Async zone executing in thread: "+ Thread.currentThread().getName());System.out.println("Simulating long running op via Thread sleep() started on "+ new Date().toString());try {Thread.sleep(5000);} catch (InterruptedException ex) {Logger.getLogger(MyAsyncRESTResource.class.getName()).log(Level.SEVERE, null, ex);}System.out.println("Completed Long running op on "+new Date().toString());System.out.println("Exiting Async zone executing in thread: "+ Thread.currentThread().getName());//creating a dummy instance of our model class (Student)Student stud = new Student(input, "Abhishek", "Apr-08-1987");resp.resume(Response.ok(stud).build());});System.out.println("Exit MyAsyncRESTResource/asyncMethod() and returned thread "+Thread.currentThread().getName()+" back to thread pool");}JAX-RS客戶端API也具有異步功能,但本文未對此進行討論。 他們絕對值得一看!
Websocket 1.0
Websocket API是Java EE工具庫(Java EE 7中引入)的全新添加 。 它促進了雙向 (服務器和客戶端發起的)通信,該通信本質上也是全雙工的(客戶端或服務器都可以隨時向彼此發送消息)。
為了使用Websocket API發送異步消息,需要使用javax.websocket.Session接口上可用的getAsyncRemote方法。 在內部,這不過是javax.websocket.RemoteEnpoint – javax.websocket.RemoteEnpoint.Async的嵌套接口的實例。 對此調用常規的sendXXX方法將導致發送過程在單獨的線程中執行。 當您考慮交換大消息或處理需要向其發送消息的大量Websocket客戶端時,這特別有用。 枯萎的方法返回一個java.util.concurrent.Future對象,或者可以以javax.websocket.SendHandler接口實現的形式注冊回調。
public void sendMsg(@Observes Stock stock) {System.out.println("Message receieved by MessageObserver --> "+ stock);System.out.println("peers.size() --> "+ peers.size());peers.stream().forEach((aPeer) -> {//stock.setPrice();aPeer.getAsyncRemote().sendText(stock.toString(), (result) -> {System.out.println("Message Sent? " + result.isOK());System.out.println("Thread : " + Thread.currentThread().getName());});});}并發實用工具1.0
Java EE并發實用程序是Java EE 7的另一個重要補充 。 它提供了一種標準的生成線程的方式–好的方面是,這些線程是容器管理的 , 而不僅僅是容器沒有上下文信息的孤立/孤立線程 。
通常,Concurrency Utilities 1.0提供了一些用于在單獨線程中執行異步任務的標準構造。 它們如下: javax.enterprise.concurrent.ManagedExecutorService 和 javax.enterprise.concurrent.ManagedScheduledExecutorService 。
為了在單獨的線程中啟動新任務,可以使用ManagedExecutorService接口提交Runnable 。 除了實現Runnable接口之外,類還可以實現javax.enterprise.concurrent.ManagedTask接口并提供javax.enterprise.concurrent.ManagedTaskListener實現,以偵聽通過ManagedExecutorService提交的任務的生命周期更改。
@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("Enter AConcurrencyUtilsExample/doGet executing in thread "+ Thread.currentThread().getName());System.out.println("initiating task . . . ");mes.execute(new AManagedTask());System.out.println("Exit AConcurrencyUtilsExample/doGet and returning thread "+ Thread.currentThread().getName() +" back to pool");}Servlet 3.0
Servlet 3.0( Java EE 6的一部分)中引入了異步HTTP,它基本上提供了在單獨的線程中執行請求并掛起處理客戶端調用的原始線程的功能。
這里的關鍵角色是javax.servlet.AsyncContext接口。 為了啟動異步處理,調用java.servlet.ServletRequest接口的startAsync方法。 為了執行核心邏輯,需要將java.lang.Runnable對象提交給AsyncContext接口的start方法。 可以選擇通過實現javax.servlet.AsyncListener來附加偵聽器,以便在Async任務執行的特定時間接收回調通知。
@Overridepublic void doGet(HttpServletRequest req, HttpServletResponse resp) {PrintWriter writer = null;try {writer = resp.getWriter();} catch (IOException ex) {Logger.getLogger(MyAsyncServlet.class.getName()).log(Level.SEVERE, null, ex);}//System.out.println("entered doGet()");writer.println("ENTERING ... " + MyAsyncServlet.class.getSimpleName() + "/doGet()");writer.println("Executing in Thread: " + Thread.currentThread().getName());//step 1final AsyncContext asyncContext = req.startAsync();//step 2asyncContext.addListener(new CustomAsyncHandler(asyncContext));//step 3asyncContext.start(() -> {PrintWriter logger = null;try {logger = asyncContext.getResponse().getWriter();} catch (IOException ex) {Logger.getLogger(MyAsyncServlet.class.getName()).log(Level.SEVERE, null, ex);}logger.println("Long running Aync task execution started : " + new Date().toString());logger.println("Executing in Thread: " + Thread.currentThread().getName());try {Thread.sleep(5000);} catch (InterruptedException e) {Logger.getLogger(MyAsyncServlet.class.getName()).log(Level.SEVERE, null, e);}logger.println("Long task execution complete : " + new Date().toString());logger.println("Calling complete() on AsyncContext");//step 4asyncContext.complete();});writer.println("EXITING ... " + MyAsyncServlet.class.getSimpleName() + "/doGet() and returning initial thread back to the thread pool");}EJB 3.1
通常,(在EJB 3.1之前)EJB消息驅動Bean用于滿足與異步相關的要求。 MDB bean偵聽發送到javax.jms.Destination ( 隊列或Topic )的消息,并執行所需的業務邏輯-從發送電子郵件到啟動訂單處理任務,這可能是任何事情。 要了解的重要一點是,首先將消息發送到Queue的客戶端不知道 MDB(已解耦 ),并且不必等待/保持阻塞,直到工作結束(電子郵件收據或訂單處理確認) )。
EJB 3.1( Java EE 6的一部分)引入了javax.ejb.Asynchronous批注。 可以將其放在EJB會話bean(無狀態,有狀態或單例) 類 (使所有方法都異步)上,也可以放在方法級別本身上(以防需要精細控制)。 如果需要跟蹤異步方法的結果,則帶有@Asynchronous批注的方法可以返回void (失火并忘記)或java.util.concurrent.Future的實例–可以通過調用Future.get()來實現 –需要注意的是, get方法本身實際上是阻塞的。
@Asynchronouspublic Future<String> asyncEJB2(){System.out.println("Entered MyAsyncEJB/asyncEJB2()");System.out.println("MyAsyncEJB/asyncEJB2() Executing in thread: "+ Thread.currentThread().getName());System.out.println("Pretending as if MyAsyncEJB/asyncEJB2() is doing something !");try {Thread.sleep(5000);} catch (InterruptedException ex) {java.util.logging.Logger.getLogger(MyAsyncEJB.class.getName()).log(Level.SEVERE, null, ex);}System.out.println("Exiting MyAsyncEJB/asyncEJB2()");return new AsyncResult("Finished Executing on "+ new Date().toString());}這是Java EE功能的簡短預覽。 這些API和規范功能豐富,很難通過博客文章涵蓋所有這些API和規范! 我希望這會激起您的興趣,并為您提供進一步探索的起點。
干杯!
翻譯自: https://www.javacodegeeks.com/2014/08/java-ee-asynchronous-constructs-and-capabilities.html
java ee打印功能
總結
以上是生活随笔為你收集整理的java ee打印功能_Java EE:异步构造和功能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国最北端的城市是哪个城市 中国最北端的
- 下一篇: 彩妆用品有哪些 一般的彩妆都有哪些东西