java - SwingUtilities.invokeLater takes a Runnable and runs it on the EDT? -
i confused signature of swingutilities.invokelater. takes runnable object. runnable object handed on event dispatch thread? why can't directly call createandshowgui on run method of edt (if possible)?
i have read articles on over how edt , invokelater work, confused runnable object passed.
swingutilities.invokelater(new runnable() { public void run() { createandshowgui(); } }); and happen if call swingutilities.invokelater again right below call?
swingutilities.invokelater(new runnable() { public void run() { createandshowgui(); } }); swingutilities.invokelater(new runnable() { public void run() { dosomethingontopofgui(); } });
what new runnable() {}?
new runnable() { public void run() { createandshowgui(); } }; this declares anonymous class , instantiates new instance of it. equivalent this:
class creator implements runnable { public void run() { createandshowgui(); } } new creator(); before java 8 lambdas, anonymous class way kind of functional programming. passing runnable invokelater passing function edt can execute later whenever wants (by calling run on it).
what invokelater runnable?
initially, create event wrap (an invocationevent) , put @ end of queue.
after queuing event, invokelater notifies edt (which wakes if waiting). edt's own run method infinite loop processes events. looks (very paraphrased):
public void run() { while(true) { eventqueue eq = geteventqueue(); synchronized(eq) { while(eq.hasnextevent()) { processoneevent(eq.getnextevent()); } try { eq.wait(); } catch(interruptedexception ie) {} } } } when edt gets new invocationevent, calls run on runnable, calls createandshowgui.
so passing runnable invokelater or invokeandwait lets run code want on edt.
how run called?
in cases, or immediately. edt responsive. 'later' part of 'invokelater' hint that:
runexecuted asynchronously. thread callsinvokelatermay continue past call before event processed.- other events may processed first.
of course invokeandwait exists alternative if synchronous call run desired. (though should noted invokeandwait may cause other events processed if queued before new invocationevent.)
asynchronous
swingutilities.invokelater(new runnable() { public void run() { system.out.println("hello"); } }); system.out.println("world"); this may print
hello world
and may print
world hello
because calling thread may or may not continue before (or while) event processed. depends on system's thread scheduler.
synchronous
swingutilities.invokeandwait(new runnable() { public void run() { system.out.println("hello"); } }); system.out.println("world"); this print
hello world
because calling thread wait run complete before continues (unless exception thrown).
invokeandwait uses wait , notify scheme achieve this. monitor object created , given invocationevent. invokeandwait calls wait after posting event , invocationevent calls notifyall after run completes on edt. wait , notify scheme reason invokeandwait cannot called on edt. edt not have way stop in middle of 1 event process different one.
what happens if more 1 event queued?
the edt processes events 1 @ time, in order queued , according priority. events can merged (a regular invocationevent not). events normal priority. paintevent (like calling repaint) typically low priority , system events of higher priorities.
in specific example you've given:
swingutilities.invokelater(new runnable() { public void run() { createandshowgui(); } }); swingutilities.invokelater(new runnable() { public void run() { dosomethingelse(); } }); since same kind of event , same priority, dosomethingelse event processed after createandshowgui event done.
similarly, if done:
swingutilities.invokelater(new runnable() { public void run() { swingutilities.invokelater(new runnable() { public void run() { system.out.println("world"); } }); system.out.println("hello"); } }); that print
hello world
because world runnable gets run after hello runnable completes.
Comments
Post a Comment