Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #30204 > unrolled thread

merging two independant Java programs into one Java program running two threads?

Started byJohn <xsli2@yahoo.com>
First post2014-10-27 06:33 -0700
Last post2014-10-27 08:09 -0700
Articles 3 — 3 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  merging two independant Java programs into one Java program running two threads? John <xsli2@yahoo.com> - 2014-10-27 06:33 -0700
    Re: merging two independant Java programs into one Java program running two threads? Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-10-27 10:57 -0400
    Re: merging two independant Java programs into one Java program running two threads? Knute Johnson <eternal@knutejohnson.com> - 2014-10-27 08:09 -0700

#30204 — merging two independant Java programs into one Java program running two threads?

FromJohn <xsli2@yahoo.com>
Date2014-10-27 06:33 -0700
Subjectmerging two independant Java programs into one Java program running two threads?
Message-ID<c306a7d8-970d-4efe-9776-cb27b69568f9@googlegroups.com>
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.

Thank you very much.

[toc] | [next] | [standalone]


#30208

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2014-10-27 10:57 -0400
Message-ID<m2lmgu$lpv$1@dont-email.me>
In reply to#30204
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

[toc] | [prev] | [next] | [standalone]


#30209

FromKnute Johnson <eternal@knutejohnson.com>
Date2014-10-27 08:09 -0700
Message-ID<m2ln7h$oup$1@dont-email.me>
In reply to#30204
On 10/27/2014 06:33, 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.
>
> Thank you very much.
>

Eric gave you a good discussion of the issues.  This is just a simple 
example of starting and stopping a Thread to do a second task in your 
GUI program.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test2 extends JFrame implements ActionListener, Runnable {
     private final JMenuItem startstop;
     private final JTextArea textArea;

     private volatile Thread thread;
     private boolean runFlag;

     public test2() {
         addWindowListener(new WindowAdapter() {
             public void windowClosing(WindowEvent we) {
                 stop();
                 dispose();
             }
         });

         JMenuBar mb = new JMenuBar();
         setJMenuBar(mb);
         JMenu file = mb.add(new JMenu("file"));

         startstop = file.add("start");
         startstop.addActionListener(this);

         textArea = new JTextArea("");
         JScrollPane scrollPane = new JScrollPane(textArea);
         add(scrollPane,BorderLayout.CENTER);

         setSize(400,300);
         setLocationRelativeTo(null);
         setVisible(true);
     }

     public void actionPerformed(ActionEvent ae) {
         switch (ae.getActionCommand()) {
             case "start":
                 textArea.append("start\n");
                 startstop.setText("stop");
                 start();
                 break;
             case "stop":
                 textArea.append("stop\n");
                 startstop.setText("start");
                 stop();
                 break;
         }
     }

     public void start() {
         runFlag = true;
         thread = new Thread(this);
         thread.start();
     }

     public void run() {
         while (runFlag) {
             // do your thing
             EventQueue.invokeLater(new Runnable() {
                 public void run() {
                     textArea.append("running\n");
                 }
             });
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException ie) {
                 EventQueue.invokeLater(new Runnable() {
                     public void run() {
                         textArea.append("sleep interrupted\n");
                     }
                 });
             }
         }
     }

     public void stop() {
         runFlag = false;
         thread.interrupt();
     }

     public static void main(String... args) {
         EventQueue.invokeLater(new Runnable() {
             public void run() {
                 new test2();
             }
         });
     }
}



-- 

Knute Johnson

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web