Setting bean properties from a thread
I have a @ViewScoped
bean that passes itself to a Thread object.
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);
}
This seems to work most of the times, but not very stable. In my view, I use PrimeFaces' p:poll
to refresh a h:inputTextarea
which displays the property I set in the thread. It works... sometimes. Sometimes I see no text at all, sometimes it only displays new text for the first poll.
The boolean property I set in the thread doesn't seem to be up to date if I call an action method from my form while the thread is running (the thread set it to false
, after that I invoke the action method from the form and isLocked()
still returns true
).
Is there any more clever way to do this? Passing a bean to a thread seems wrong to me. But how else could I achieve this?
开发者_开发百科UPDATE
My goal is as follows: I want the user to be able to see changes made to some files that lie on a remote server (without refreshing). Basically, I want the user to see a tail -f
of a remote file in an inputTextarea
. (The connection to the remote server is done by the thread using SSH [Ganymed library]).
So I put the inputTextarea
in the form and refresh it using p:poll
. I update the String that is bound to the inputTextarea
in the thread (the user invokes the action that will start the thread using a commandButton
. Also, I want the user to stop the tail -f
via a selectBooleanCheckbox
. So I put a condition in the run()
method of the thread:
if(someBean.isFinished()) {
// logout and break;
}
The changes made to the selectBooleanCheckbox
are reflected in the run method straight away because I used <f:ajax />
- but bean properties set from the run method are sometimes not "updated" right away.
I'm using Tomcat 7.0.12, JSF 2 (MyFaces) and PrimeFaces 2.2.1
Managed beans in JSF are inherently volatile so this approach is completely wrong.
The Primefaces <p:poll>
object handles routine refreshes for you that you will be able to post back on a repeated interval to get the next set of results.
Here is the following code sample that is available on the Primefaces demo page of how this component should be used.
<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>
Here is a link to view how the Primefaces demo should work: Poll
What you should do is on each call to the listener
method of your managed bean, check for the latest updates on your filesystem and then update the contents of your managed bean.
精彩评论