pass-by-reference(of StringBuffer) to a constructor of another class

S

sravan_reddy001

I had a problem with pass-by reference...

i have two classes in my application, and one class should send a
string to other..

the problem is....

the two classes are implements Runnable and one Class extends Thread.
and this a Networking application
in the run method of class A, i am creating an object of class B
calling is as

A's prog:

public void run()
{
Socket s=sc.accept();
StringBuffer c=new StringBuffer;
B c=new B(s,c);
---> the new value of b is not available here
}

B's prog:

B(Socket a,StringBuffer b)
{
string mm;
this.start();
b=b.append(mm);
}
public void run()
{
mm="message";
}
 
L

Lasse Reichstein Nielsen

sravan_reddy001 said:
I had a problem with pass-by reference...

In Java?
i have two classes in my application, and one class should send a
string to other.. ....
the two classes are implements Runnable and one Class extends Thread.
and this a Networking application
in the run method of class A, i am creating an object of class B
calling is as

A's prog:

Please post the *entire* class, and as compilable code.
<URL:http://mindprod.com/jgloss/sscce.html>

I'll assume that this method is merely wrapped in
public class A implements Runnable {
...
}
public void run()
{
Socket s=sc.accept();
StringBuffer c=new StringBuffer;
B c=new B(s,c);
---> the new value of b is not available here

What b? There is no b here. Do you mean that c is not updated?

What were you expecting? How would you test it?
}

B's prog:

Here I'll assume that this constructor and method is in a class defined
as

public class B extends Thread {
...
}
B(Socket a,StringBuffer b)
{
string mm;

This is not the code you are using. String should be capitalized,
and I'm guessing this should be a field, not a variable local
to the constructor.
this.start();

Starting itself in the constructor is extremely bad style. This means
that other parts of the object might be run *before* the constructor
finishes. Or they might not. Nobody knows.
b=b.append(mm);

Most likely the thread has not started running its run method yet, so
mm is still null at this point.
}
public void run()
{
mm="message";

Again, I'm assuming mm is a field.


Your problem is with threading. You can't know when the new thread you
started has finished, unless you use synchronization to fix the
execution order of the two threads, or if you wait for the thread to
finish. Even then you need synchronization to ensure that the update
of mm performed by the other thread is visible.
 
S

sravan_reddy001

i am very sorry to present my question that doesn't convey correct
meaning...

this file acts as server...

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Message implements Serializable
{
String mesg;
}
class server1 extends JFrame implements ActionListener,Runnable
{
JPanel p;
JTextArea ta;
JScrollPane sp;
JLabel l;
JTextField txt;
JButton b;
Socket cl;
String str;
ServerSocket sc;
Thread th;
Socket s;
//public String temp;

protected ObjectInputStream client;
protected ObjectOutputStream cli;

server1()
{
super("Client Window");
th=new Thread(this);
p=new JPanel();
//temp=new Message();
ta=new JTextArea(10,20);
sp=new JScrollPane(ta);
l=new JLabel("Enter Message ");
txt=new JTextField(15);
b=new JButton("Submit");
try
{
sc=new ServerSocket(1001);
}
catch (Exception e)
{
//JOptionPane.showMessageDialog(null,"Socket Error");
}
p.add(sp);
p.add(l);
p.add(txt);
p.add(b);
getContentPane().add(p);
setSize(300,300);
setVisible(true);
b.addActionListener(this);
th.start();
}
public void actionPerformed(ActionEvent ae)
{
try
{
str=txt.getText();
txt.setText("");
Message m1=new Message();
m1.mesg=str;
if (str.equals("")==false)
{
cli=new ObjectOutputStream(s.getOutputStream());
cli.writeObject((Message)m1);
ta.append("\nServer : "+str);
}
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null,""+e);
}
}
public void run()
{
while (true)
{
try
{
s=sc.accept();
Message temp=new Message();
connection cn=new connection(s,temp);
if(temp.mesg.equals("")==false)
ta.append("\nClient : "+temp.mesg);
//JOptionPane.showMessageDialog(null,""+temp);
}
catch (Exception e)
{
}
/*try
{
Thread.sleep(500);
}
catch (Exception e)
{
}*/
}
}
public static void main(String args[])
{
new server1();
}
}
class connection extends Thread
{
protected Socket cs;
protected ObjectInputStream client;
protected ObjectOutputStream cli;
protected PrintStream ps;
String mm,abc;
public connection(Socket sr,Message toser)
{
cs=sr;
try
{
client=new ObjectInputStream(cs.getInputStream());
//cli=new ObjectOutputStream(cs.getOutputStream());
}
catch (Exception e1)
{
try
{
cs.close();
}
catch (Exception e2)
{
}
}
this.start();
//toser.mesg=mm;
//abc=new String(""+mm.toString());

// the main probem is here....
// the value of mm is not assigned to toser.mesg--> please suggest
me a solution
//


toser.mesg=new String(mm);
JOptionPane.showMessageDialog(null,""+toser.mesg);
JOptionPane.showMessageDialog(null,""+abc);
}
public void run()
{
Message msg1;
try
{
for(;;)
{
msg1=(Message)client.readObject();
if(msg1==null)
break;
mm=msg1.mesg;
//mm="chanti gadu";
System.out.println("Client Message : "+mm);
}
}
catch (Exception e3)
{
}
finally
{
try
{
cs.close();
}
catch (Exception e4)
{
}
}
}
}
 
L

Lasse Reichstein Nielsen

sravan_reddy001 said:
s=sc.accept();
Message temp=new Message();
connection cn=new connection(s,temp);
if(temp.mesg.equals("")==false)
ta.append("\nClient : "+temp.mesg); ....
class connection extends Thread
{ ....
String mm,abc;
public connection(Socket sr,Message toser)
{
cs=sr; ....
this.start();
....

I still maintain that you should not start a thread in its constructor.
It allows another thread to see the object before it was completely
constructed.
Instead create a static factory method that creates the object and
then starts it.
// the main probem is here....
// the value of mm is not assigned to toser.mesg--> please suggest
me a solution
//
toser.mesg=new String(mm);

At this time, mm most likely still has the value null.
What value do you expect it to have?
Do you have to wait for a message to be available?

....
public void run()
{
Message msg1;
try
{
for(;;)
{
msg1=(Message)client.readObject();
if(msg1==null)
break;
mm=msg1.mesg;

This assignment will happen eventually, but it is highly unlikely to
happen before the thread starting this thread has executed its next
statement.

If you need two threads to communicate, you should use serialization
to enforce it. In this case, you will need to wait for mm to change,
if you want the new value. But don't wait inside a constructor!
 
S

sravan_reddy001

i hav one more prob..

if i run the thread not from the constructor...
how can i send an Message object as a parameter... and how can i get
that value in the server1 class ..
since run() method cannot return an object

the run method of class connection will have the actual message.. i
wan't that message in server1 class
 
S

sravan_reddy001

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Message implements Serializable
{
String mesg;
}
class server1 extends JFrame implements ActionListener,Runnable
{
JPanel p;
JTextArea ta;
JScrollPane sp;
JLabel l;
JTextField txt;
JButton b;
Socket cl;
String str;
ServerSocket sc;
//Thread th;
Socket s;
//public String temp;

protected ObjectInputStream client;
protected ObjectOutputStream cli;

server1()
{
super("Client Window");
//th=new Thread(this);
p=new JPanel();
//temp=new Message();
ta=new JTextArea(10,20);
sp=new JScrollPane(ta);
l=new JLabel("Enter Message ");
txt=new JTextField(15);
b=new JButton("Submit");
try
{
sc=new ServerSocket(1001);
}
catch (Exception e)
{
//JOptionPane.showMessageDialog(null,"Socket Error");
}
p.add(sp);
p.add(l);
p.add(txt);
p.add(b);
getContentPane().add(p);
setSize(300,300);
setVisible(true);
b.addActionListener(this);
//th.start();
}
public void actionPerformed(ActionEvent ae)
{
try
{
str=txt.getText();
txt.setText("");
Message m1=new Message();
m1.mesg=str;
if (str.equals("")==false)
{
cli=new ObjectOutputStream(s.getOutputStream());
cli.writeObject((Message)m1);
ta.append("\nServer : "+str);
}
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null,""+e);
}
}
public void run()
{
while (true)
{
try
{
s=sc.accept();
Message temp=new Message();
connection cn=new connection(s,temp);
cn.start();
if(cn.mm.equals("")==false)
ta.append("\nClient : "+cn.mm);
JOptionPane.showMessageDialog(null,""+cn.mm);
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null,"Error : "+e);
}
/*try
{
Thread.sleep(500);
}
catch (Exception e)
{
}*/
}
}
public static void main(String args[])
{
server1 a=new server1();
Thread th=new Thread(a);
th.start();
}
}
class connection extends Thread
{
protected Socket cs;
protected ObjectInputStream client;
protected ObjectOutputStream cli;
protected PrintStream ps;
public String mm,abc;
public connection(Socket sr,Message toser)
{
cs=sr;
try
{
client=new ObjectInputStream(cs.getInputStream());
//cli=new ObjectOutputStream(cs.getOutputStream());
}
catch (Exception e1)
{
try
{
cs.close();
}
catch (Exception e2)
{
}
}
mm="abc";
//this.start();
//toser.mesg=mm;
/*try
{
toser.mesg=new String(""+mm);
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null,"Error : "+e);
}
System.out.println("abc value : "+abc);

JOptionPane.showMessageDialog(null,""+toser.mesg);
JOptionPane.showMessageDialog(null,""+abc);*/
}
public void run()
{
Message msg1;
try
{
for(;;)
{
msg1=(Message)client.readObject();
if(msg1==null)
break;
mm=msg1.mesg;
//mm="chanti gadu";
System.out.println("Client Message : "+mm);
JOptionPane.showMessageDialog(null,"value : "+mm);
}
}
catch (Exception e3)
{
JOptionPane.showMessageDialog(null,"Error : "+e3);
}
finally
{
try
{
cs.close();
}
catch (Exception e4)
{
}
}
}
}


this is new program...
how can pause the execution the of thread(that represents the server1)
until the run() of class connection is executed...
 
M

Mark Space

sravan_reddy001 said:
i hav one more prob..

if i run the thread not from the constructor...
how can i send an Message object as a parameter... and how can i get
that value in the server1 class ..
since run() method cannot return an object

the run method of class connection will have the actual message.. i
wan't that message in server1 class

I didn't look at your new program, but on returning an object from run()
you can:

1. Use a Callable object instead of a Thread.

2. Store the result in a public field in your Thread and have another
object retrieve it after your Thread has completed (or some other signal
occurs). Actually it might be better to use a method here and provide
the synchronization in the method.
 
S

sravan_reddy001

Thanks..

i don't know how to use Callable objects... i will find it how to
that...

i now got the program working.. thanks a lot..

Have a prob in networking... posting in another thread..

thanks a lot....
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,218
Latest member
JolieDenha

Latest Threads

Top