Reputation: 3
I've written a simple chat server, but i don't have an idea how to send message to another thread. What i've tried returns an error:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
class ConnectorService extends Thread {
Socket connection;
ObjectInputStream in;
ObjectOutputStream out;
Thread _t;
public ConnectorService( Socket sock, ObjectInputStream _in, ObjectOutputStream _out ) {
this.connection = sock;
try {
in = _in;
out = _out;
out.flush( );
}
catch( Exception e ) {
System.err.println( "Wystapil blad laczenia do socketu.." );
}
}
@Override
public void run() {
this.send( "Siemka :P" );
while( true ) {
try {
String mess = (String)in.readObject( );
String[] m = mess.split( ":" );
if( m.length > 1 ) {
Thread _tmp;
if( ( _tmp = getThreadByName( m[ 0 ] ) ) != null ) {
// Here i've got an exception
( ( ConnectorService ) _tmp ).send( m[ 1 ] );
}
}
else {
System.err.println( "Zbyt malo argumentow.." );
}
this.getThreadByName( "test" );
System.out.println( "Klient: " + mess );
this.send( mess );
}
catch( ClassNotFoundException e ) {
System.err.println( "Bledny typ wiadomosci.." );
}
catch (IOException e) {
// e.printStackTrace();
System.err.println( "Polaczenie przerwane.." );
break;
}
}
}
public void start( ) {
System.out.println( "Uruchamiam klienta" );
if( _t == null ) {
_t = new Thread( this );
_t.start();
}
}
public void send( String message ) {
try {
out.writeObject( message );
out.flush();
}
catch( IOException e ) {
e.printStackTrace( );
}
}
public Thread getThreadByName(String threadName) {
for (Thread t : ConnectorService.getAllStackTraces().keySet()) {
if (t.getName().equals(threadName)) return t;
//System.out.println( t.getName() );
}
return null;
}
}
I've tried to cast a thread that i get from method getThreadByName()
, but then i've received an exception that i cannot cast a thread..
Is the any possibility to call that method in another thread? Greetings
Upvotes: 0
Views: 894
Reputation:
Like alamar said, using a message queue would be better, but since you are using this for a simple program, here's a simple solution:
You need to keep a list of references to each thread you make, and also keep the name of each thread, maybe using a map:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
class ConnectorService extends Thread {
static Map<String, Thread> connectorServices = new HashMap<>();
Socket connection;
ObjectInputStream in;
ObjectOutputStream out;
Thread _t;
public ConnectorService(String name, Socket sock, ObjectInputStream _in, ObjectOutputStream _out) {
this.connection = sock;
try {
in = _in;
out = _out;
out.flush();
} catch (Exception e) {
System.err.println("Wystapil blad laczenia do socketu..");
}
// add this to the list of references to the threads
ConnectorService.connectorServices.put(name, this);
}
@Override
public void run() {
this.send("Siemka :P");
while (true) {
try {
String mess = (String) in.readObject();
String[] m = mess.split(":");
if (m.length > 1) {
Thread _tmp;
if ((_tmp = getThreadByName(m[0])) != null) {
// Here i've got an exception
((ConnectorService) _tmp).send(m[1]);
}
} else {
System.err.println("Zbyt malo argumentow..");
}
this.getThreadByName("test");
System.out.println("Klient: " + mess);
this.send(mess);
} catch (ClassNotFoundException e) {
System.err.println("Bledny typ wiadomosci..");
} catch (IOException e) {
// e.printStackTrace();
System.err.println("Polaczenie przerwane..");
break;
}
}
}
public void start() {
System.out.println("Uruchamiam klienta");
if (_t == null) {
_t = new Thread(this);
_t.start();
}
}
public void send(String message) {
try {
out.writeObject(message);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public Thread getThreadByName(String threadName) {
return ConnectorService.connectorServices.get(threadName);
}
}
This code should compile and work fine...
BUT notice how I did not use proper encapsulation - I'll leave that up to you to do...
Upvotes: 2
Reputation: 19343
There's a huge blob of knowledge called concurrent programming and it seems that you have to learn it from the start.
What you are trying to do is wait/notify (google it up). You wait in one thread in synchronized block on object, then other thread calls notify on the same object and that thread wakes up. You can probably put message in that object to effectively pass it.
But it's a rudimentary way to do concurrent programming. What you really want here is some kind of concurrent queue. Issue blocking read in one thread, write message to queue in another - first thread will un-block and get the message. https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
Upvotes: 2