高级ZK:异步UI更新和后台处理–第1部分
長時(shí)間運(yùn)行的處理
有時(shí),您可能需要進(jìn)行數(shù)據(jù)庫查詢,或者需要很長時(shí)間才能進(jìn)行外部Web服務(wù)調(diào)用。 通常,這些作業(yè)是同步的,因此基本上在代碼中有一個(gè)特定的點(diǎn),系統(tǒng)將必須等待結(jié)果并阻塞運(yùn)行該代碼的線程。 如果最終在UI線程中運(yùn)行了這樣的代碼,則通常會(huì)完全阻塞UI。
實(shí)時(shí)更新
有時(shí)您不預(yù)先知道應(yīng)該更新UI中的某些內(nèi)容的確切時(shí)間。 例如,您可以使用一個(gè)可視儀表來顯示應(yīng)用程序中的用戶數(shù)量。 當(dāng)新用戶進(jìn)入應(yīng)用程序時(shí),應(yīng)盡快更新當(dāng)前用戶的UI,以反映新用戶數(shù)。 您可以使用基于計(jì)時(shí)器的機(jī)制來連續(xù)檢查用戶數(shù)量是否已更改,但是如果同時(shí)存在的用戶過多,則即使UI中沒有實(shí)際更新的內(nèi)容,連續(xù)檢查也將導(dǎo)致非常重的負(fù)載。
基本概念
讓我們首先摘錄此博客文章的標(biāo)題:“異步UI更新和后臺(tái)處理”
后臺(tái)處理
在長時(shí)間運(yùn)行的處理用例中,減少UI阻塞的最明顯方法是將昂貴的處理從UI線程轉(zhuǎn)移到某些后臺(tái)線程。 能夠理解哪種線程將在應(yīng)用程序的不同部分中運(yùn)行代碼非常重要。 例如,在ZK應(yīng)用程序中,大多數(shù)代碼由servlet線程執(zhí)行,這些線程基本上是與UI線程等效的servlet世界。 為了在某??些后臺(tái)線程中執(zhí)行代碼,我們需要一個(gè)線程池。 最簡單的方法是使用JDK5中引入的java.util.concurrent.ExecutorService。 我們可以將Runnable對(duì)象推送到ExecutorService,因此我們基本上是在要求ExecutorService在某些后臺(tái)線程中運(yùn)行特定的代碼塊。
絕對(duì)關(guān)鍵的是,使用ThreadLocals的框架會(huì)遇到這種方法的問題,因?yàn)樵趕ervlet線程中設(shè)置的ThreadLocals在后臺(tái)線程中將不可見。 一個(gè)示例是Spring Security,默認(rèn)情況下使用ThreadLocal來存儲(chǔ)安全上下文(=用戶身份+其他東西)。
異步UI更新
在這種情況下,異步UI更新意味著什么? 基本上,這個(gè)想法是,一旦我們有了一些要在UI中呈現(xiàn)的信息,我們就會(huì)通知UI新數(shù)據(jù)(=異步),而不是直接在后臺(tái)線程中更新UI(=同步)。 我們無法事先知道新信息何時(shí)可用,因此我們無法從客戶端請(qǐng)求信息(除非我們使用昂貴的輪詢)。
服務(wù)器推送ZK
使用ZK,基本上,有兩種不同的方法可以在后臺(tái)線程獲得新信息后用于更新UI。 名稱“服務(wù)器推送”來自以下事實(shí):服務(wù)器具有一些必須推送到客戶端的新數(shù)據(jù),而不是典型的工作流程(客戶端向服務(wù)器詢問信息)。 首先,可以通過使用Executions.activate / deactivate搶占對(duì)桌面的獨(dú)占訪問權(quán)限來進(jìn)行同步更新。 我個(gè)人不建議這樣做,因?yàn)橐坏┠鷵碛歇?dú)占訪問權(quán),UI線程將不得不等待直到停用桌面。 這就是為什么我在這篇博客文章中根本不會(huì)介紹這種方法的原因。
另一方面,異步更新是通過使用Executions.schedule完成的,它符合常規(guī)事件處理的Event / EventListener模型。 這個(gè)想法是,我們可以將普通的ZK Event對(duì)象推送到EventListeners,客戶端將被告知這些事件。 之后,ZK使用Javascript進(jìn)行正常的AJAX請(qǐng)求,事件將由EventListeners處理。 這意味著,如果我們使用異步更新,則所有實(shí)際的事件處理將由Servlet線程完成,并且所有ThreadLocals照常可用。 這使編程模型非常簡單,因?yàn)槟恍枰胀ǖ氖录陕犉鞣椒?#xff0c;而無需復(fù)雜的并發(fā)編程。
這是一個(gè)小例子:
public class TestComposer extends GenericForwardComposer {private Textbox search;public void onClick$startButton() {if (desktop.isServerPushEnabled()) {desktop.enableServerPush(true);}final String searchString = search.getValue();final EventListener el = this; // All GenericForwardComposers are also EventListeners// Don't do this in a real-world application. Use thread pools instead.Thread backgroundThread = new Thread() {public void run() {// In this part of code the ThreadLocals ARE NOT available// You must NOT touch any ZK related things (e.g. components, desktops)// If you need some information from ZK, you need to get them before this code// For example here I've read searchString from a textbox, so I can use the searchString variable without problemsString result = ... // Retrieve the result from somewhereExecutions.schedule(desktop, el, new Event('onNewData', null, result));}};backgroundThread.start();}public void onNewData(Event event) {// In this part of code the ThreadLocals ARE availableString result = (String) event.getData();// Do something with result. You can touch any ZK stuff freely, just like when a normal event is posted.} }在下一部分中,我將向您展示如何使用JDK5 ExecutorServices來運(yùn)行任務(wù)而無需手動(dòng)創(chuàng)建線程。 如果您真的想了解ZK服務(wù)器推送,還應(yīng)該閱讀相關(guān)的ZK文檔 。
祝您編程愉快,別忘了分享!
參考: Advanced ZK:異步UI更新和后臺(tái)處理– Jawsy Solutions技術(shù)博客博客上的JCG合作伙伴 Joonas Javanainen的第1部分 。
翻譯自: https://www.javacodegeeks.com/2012/09/advanced-zk-asynchronous-ui-updates-and.html
總結(jié)
以上是生活随笔為你收集整理的高级ZK:异步UI更新和后台处理–第1部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 商品备案资料怎么写(商品备案资料)
- 下一篇: Apache Wicket:记住我的功能