Path: csiph.com!usenet.pasdenom.info!aioe.org!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: merging two independant Java programs into one Java program running two threads? Date: Mon, 27 Oct 2014 10:57:39 -0400 Organization: A noiseless patient Spider Lines: 100 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Mon, 27 Oct 2014 14:57:34 +0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="bd4e1cba8d8592bec5d5ed9e4537fbfd"; logging-data="22335"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18KjpecuT9BtQzrXw5sFZGQ" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 In-Reply-To: Cancel-Lock: sha1:fs33sK9dU3BD/QEx/TumPF8Xips= Xref: csiph.com comp.lang.java.programmer:30208 On 10/27/2014 9:33 AM, John wrote: > Hi: > > I have two independent Java programs. Program A is a GUI program. Program B continuously take screen shots every 5 seconds and save them into PNG picture files. > > Right now, I start running Java Program B first, then start Program A, doing GUI interaction etc. > > I hope to merge the two into one Java program which runs the original two programs by two interdependent processes or threads(not sure which one is correct. Help please). And I would like to have this feature: when GUI interaction by me proceeds to certain stage, e.g. when I click Button 'XYZ' on the GUI, the process/thread taking screen shots halts. After a while, when I click another button, the halted process/thread proceeds again. At the end, when I quit the GUI program, the process/thread taking the screen shots ends as well. > > I think this makes me learn multi-thread programming or inter-process communication. If you could shed some light on this project, I would greatly appreciate it. This can be done with two threads or with two processes. (The distinction: Two threads can run in the same Java Virtual Machine in one process, or two processes each with its own JVM can run one thread apiece.) It will be easier with two threads in one JVM, because it's easier to communicate between activities in the same JVM than to chat with an activity in a different JVM. Either way, though, the notion of "independent programs" is not tenable. You want Program B's behavior to depend on the state of Program A, which it could not do if they were independent. Program B needs to be made aware of what's going on in A, or else it can't know when to collect screen captures and when to sit idle. There are many ways to arrange the behavior you describe, but I think the simplest might be for A to maintain a public field that describes its own state: running (hey, look at me!), hidden (no peeking, please), or finished: enum State { RUNNING, HIDDEN, FINISHED }; class StateHolder { private State current; synchronized void setState(State newState) { current = newState; notifyAll(); // in case someone's in wait() } synchronized State getState() { return current; } } class A { ... public final StateHolder state = new StateHolder(); ... // A is starting and allows B to view it: state.setState(RUNNING); ... // A wants some privacy: state.setState(HIDDEN); ... // A is about to stop running: state.setState(FINISHED); ... } Meanwhile, class B can run on a Timer (or similar) that executes it every five seconds regardless of what A is doing -- *except* that each time B runs it checks A's status: class B implements Runnable { private final A myPartner; ... public B(A partner) { this.myPartner = partner; ... } ... @Override public void run() { // Arrange to have the Timer (or whatever) execute this // method periodically. synchronized (myPartner.state) { while (myPartner.state.getState() == State.HIDDEN) { myPartner.state.wait(); // ... for notifyAll() } if (myPartner.state.getState() == State.FINISHED) { // A's finished; B should now finish, too. } } // A is neither HIDDEN nor FINISHED, hence RUNNING: // do the screen capture and return, then let the Timer // re-execute "by and by." } ... } This is a very basic -- some might say "crude" -- way to accomplish your goal, and there are many others with different characteristics and different degrees of sophistication. You might choose to do things a little differently from what I've shown. For example, if the B above finds its A in the HIDDEN state it blocks until the state changes to something else, probably disrupting the regularity of the timed events. You might instead decide to have B simply return if A is HIDDEN, the idea being that the Timer will re-awaken it soon for another try. It depends what you want ... -- esosman@comcast-dot-net.invalid