Wojciech
Wojciech

Reputation: 3

Calling a method from another thread in java

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

Answers (2)

user5182794
user5182794

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

alamar
alamar

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

Related Questions