Passing attributes between threads

My program has 3 threads:
1. the main thread of execution
2. A thread to listen on a port
3. A Session thread (multiple)

I want to be able to pass a socket object from my thread listening on the port to the main thread of execution, which then chooses which session thread to manage the socket.


Is there anyway of sending the socket to the main thread of execution, whilst keep the thread listening on the port with a new socket Alive?
plaskowjAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AMD_MANCommented:

You can use PipedInputStream/PipedOutputStream from the java.io package to share data between threads in particular.  This is a way of sending data like you are describing between threads.

AMD_MAN
0
plaskowjAuthor Commented:
Can you give me a brief example of passing an object between a thread and the main thread of execution

and then i will reward you highly
0
loumfCommented:
One way to do this is to have a Vector of sockets that you add the socket to and have the main thread periodically check the vector and remove the sockets to give to a session thread.

I think a slightly better way is to dedicate a thread to dealing with choosing session threads rather than use the main thread.  That way you can use the nofication mechanism to make sure that sockets are handled immediately.  This new thread is mostly sleeping (waiting for sockets to be added to the vector)

Here's pseudo code for the new thread class (I haven't compiled it, but it should be basically ok)--you need to figure out how to make this thread exit--probably by checking a flag on each iteration.

private Vector socketVector_;
public void run()
{
  while (true) {
    synchronized(socketVector_) {
      // if the vector has elements
      // send them to sessions
      for (int i=0; i<socketVector_.size(); ++i) {
        // replace this with your mechanism
        SendToSession(socketVector_[i]);
      }
      socketVector_.removeAllElements();

      // wait for sockets (this releases
      // the lock on socketVector_
      socketVector_.wait();
    }
  }
}

// call this from the socket server
// thread whenever you get a connection
public void AddSocket(Socket s)
{
  synchronized(socketVector_) {
    socketVector_.addElement(s);
    // wake up the other thread
    socketVector_.nofify();
  }
}
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

plaskowjAuthor Commented:
Can you give me a brief example of passing an object between a thread and the main thread of execution

and then i will reward you highly
0
plaskowjAuthor Commented:
Where does sendToSession reside?

0
loumfCommented:
SendToSession is your code.  It is whatever you do to give the socket to a session thread.  You said that the main thread would choose to send it to a session thread.  This is the code that should appear here.

If you create new session threads this is the place to do it.  If you have to pass it to a running thread then you need to use a mechanism like this one there too (a vector of incoming sockets to handle)



0
JodCommented:
Number of ways to do this...

Here is an example using piped streams from inquiry.com.

Generator fills its output pipe with integers from 1 to 100. Filter reads from its input stream, and places only even inputs into its output stream. Amplifier reads numbers from its input stream, and places their squares in its output stream. Finally, accumulator accumulates the sum of all inputs from its input stream.

*/

import java.io.*;

// Generators fill output pipe with ints from first to last
class Generator extends Thread {

   private DataOutputStream dout;
   private int first, last;

   public Generator(PipedOutputStream out, int start, int end) {
      // filter pipes into data streams
      dout = new DataOutputStream(out);
      first = start;
      last = end;
   }

   public void run() {

      for(int i = first; i <= last; i++) {
         try {
            dout.writeInt(i);
            sleep(5); // don't be selfish
         }
         catch(IOException e) {}
         catch(InterruptedException e){}
      }
   }

} // Generator

// Accumulators sum all ints in input pipe
class Accumulator extends Thread {

   private DataInputStream din;
   private int accum = 0;

   public Accumulator(PipedInputStream in) {
      // filter pipes into data streams
      din = new DataInputStream(in);
   }

   public void run() {

      boolean done = false;

      while(!done) {
         try {
            accum += din.readInt();
            sleep(5);
         }
         catch(IOException e) { done = true; }
         catch(InterruptedException e) {}
      }

      System.out.println("Result = " + accum); // for now
   }
} // Accumulator

// Filters put even ints from input stream into
// output stream (i.e. they filter out odds)
class Filter extends Thread {

   private DataInputStream din;
   private DataOutputStream dout;
   private int next;

   public Filter(PipedInputStream in, PipedOutputStream out) {
      // filter pipes into data streams
      din = new DataInputStream(in);
      dout = new DataOutputStream(out);
   }

   public void run() {

      boolean done = false;

      while(!done) {
         try {
            next = din.readInt();
            if (next % 2 == 0)
               dout.writeInt(next);
            sleep(5);
         }
         catch(IOException e) { done = true; }
         catch(InterruptedException e) {}
      }
   }
} // Filter

// Amplifiers put squares of ints from input stream
// into output stream
class Amplifier extends Thread {

   private DataInputStream din;
   private DataOutputStream dout;
   private int next;

   public Amplifier(PipedInputStream in, PipedOutputStream out) {
      din = new DataInputStream(in);
      dout = new DataOutputStream(out);
   }

   public void run() {

      boolean done = false;

      while(!done) {
         try {
            next = din.readInt();
            dout.writeInt(next * next);
            sleep(5);
         }
         catch(IOException e) { done = true; }
         catch(InterruptedException e) {}
      }
   }
} // Amplifier

// computes sum of even squares of ints from 1 to 100
// = 2^2 + 4^2 + ... + 98^2 + 100^2
public class SumOfEvenSquares {

   public static void main(String args[]) {

      try {

         // make some pipes
         PipedOutputStream pipe1 = new PipedOutputStream();
         PipedInputStream pipe2 = new PipedInputStream(pipe1);
         //try { pipe1.connect(pipe2); } catch(IOException e) {}
         PipedOutputStream pipe3 = new PipedOutputStream();
         PipedInputStream pipe4 = new PipedInputStream(pipe3);
         //try { pipe3.connect(pipe4); } catch(IOException e) {}
         PipedOutputStream pipe5 = new PipedOutputStream();
         PipedInputStream pipe6 = new PipedInputStream(pipe5);
         //try { pipe5.connect(pipe6); } catch(IOException e) {}

         // make some threads
         Generator g = new Generator(pipe1, 1, 10);
         Filter f = new Filter(pipe2, pipe3);
         Amplifier a = new Amplifier(pipe4, pipe5);
         Accumulator ac = new Accumulator(pipe6);

         // start threads
         g.start();
         f.start();
         a.start();
         ac.start();

         // close pipes
         pipe1.close();
         pipe2.close();
         pipe3.close();
         pipe4.close();
         pipe5.close();
         pipe6.close();
     }
     catch(IOException e) {}
   }
} // SumOfEvenSquares
0
JodCommented:
To make the above example work with objects instead of primitive types, all you have to do is wrap them with ObjectInputStream and ObjectOutputStream and also make your  object implement the Serializable interface, so that it may be written to an ObjectInputStream.

Therefore, you can use this method to send any streamable data down the pipe.
0
JodCommented:
Secondly, you could also use a sort of observer/observable pattern. So, when you want to notify your main class that a new Socket needs to be given a session then you call notifyObservers from your socket creation thread and this will invoke the update method in your main thred. This main thread can then do the resource allocation for the socket.

Some overview details are here:

http://bade.ii.metu.edu.tr/resources/docs/java/langspec-1.0/javautil.doc6.html

In your case, your socket thread needs to invoke a method in your main thread somehow which should really be synchronised to avoid any concurrency issues.


Also, is your main thread waiting idle until the socket thread wakes it up?

If so you can use the Thread wait method in your main thread and use notify in your socket thread to wake up main. When main wakes up it knows that there is a new socket to retrieve from the socket thread.

Main will need a reference to the socket thread and a public method to return the socket object. Best to return an array of socket objects so that if there is more than one waiting then they are all returned and none are lost.


If you have any more questions let me know, bbut I don't have time at the mo to be more specific here.
0
plaskowjAuthor Commented:
i think I will go with the Observer method -who ever suggested this , reference so i can give points

many thanks
0
JodCommented:
It was me....

This link will give you a complete theoretical description of hoe this particular software pattern is intended to work...

http://www.inf.fu-berlin.de/~bokowski/Observer.html

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mbormannCommented:
:)
0
mbormannCommented:
Pls close this question,else gets autodeleted after 20 days of no activity.
0
JodCommented:
I have been away too long - cheers mb...
0
JodCommented:
And of course plaskowj - where are my manners....
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Editors IDEs

From novice to tech pro — start learning today.