从线程设置bean属性

时间:2011-06-14 12:59:54

标签: multithreading jsf primefaces

我有一个@ViewScoped bean,它将自己传递给Thread对象。

class SomeThread implements Runnable {
  private SomeBeanClass someBean;
  public SomeThread(SomeBeanClass someBean) {
    this.someBean = someBean;
  }

  public void run() {
    // do some calculations and set bean properties    
    someBean.setProperty("blabla");
    someBean.setLocked(false);
  }

这似乎在大多数时候都有效,但不是很稳定。在我看来,我使用PrimeFaces'p:poll来刷新h:inputTextarea,它显示我在线程中设置的属性。它有效......有时候。有时候我根本看不到任何文字,有时它只显示第一次投票的新文字。

我在线程中设置的boolean属性似乎不是最新的,如果我在线程运行时从我的表单调用一个action方法(线程将其设置为false,之后我调用表单中的操作方法和isLocked()仍会返回true)。

还有更聪明的方法吗?将bean传递给线程对我来说似乎不对。但我怎么能做到这一点?

更新

我的目标如下:我希望用户能够看到对位于远程服务器上的某些文件所做的更改(无需刷新)。基本上,我希望用户在tail -f中看到inputTextarea远程文件。 (与远程服务器的连接由线程使用SSH [Ganymed库])完成。

所以我将inputTextarea放在表单中并使用p:poll刷新它。我更新了绑定到线程中inputTextarea的String(用户调用将使用commandButton启动线程的操作。此外,我希望用户停止tail -f通过selectBooleanCheckbox。所以我在线程的run()方法中添加了一个条件:

if(someBean.isFinished()) {
  // logout and break;
}

selectBooleanCheckbox所做的更改会立即反映在run方法中,因为我使用了<f:ajax /> - 但是从run方法设置的bean属性有时不会立即“更新”。

我正在使用Tomcat 7.0.12,JSF 2(MyFaces)和PrimeFaces 2.2.1

1 个答案:

答案 0 :(得分:3)

JSF中的托管bean本质上是不稳定的,因此这种方法完全错误。

Primefaces <p:poll>对象为您处理例行刷新,您可以在重复的时间间隔内回发以获得下一组结果。

以下是Primefaces演示页面上有关如何使用此组件的代码示例。

<h:form>

    <p:commandButton type="button" value="Start"
            image="ui-icon-play" onclick="poll.start()" />
    <p:commandButton type="button" value="Stop"
            image="ui-icon-pause" onclick="poll.stop()" />

    <h:outputText id="txt_count" value="#{counterBean.count}" />

    <p:poll interval="4" listener="#{counterBean.increment}"
            update="txt_count" widgetVar="poll" autoStart="false"/>

</h:form>

以下是查看Primefaces演示应如何运作的链接:Poll

您应该做的是每次调用托管bean的listener方法,检查文件系统的最新更新,然后更新托管bean的内容。