My server aperiodically receives join requests from new clients. Upon receiving a new join request, the server runs a service that can be finished real quick. I implement the service as a Java class (called JC) implementing the Runnable interface. I have parameters within the JC class.
At the caller side, I like to have only one instance (or static) of the JC. My question is how to trigger the run() method in the JC every time. Please show me some code. Thanks.
Hope following edits make sense, which is my current implementation.
In the Server that wants to trigger thread executing:
public class Server {
private static RealService mm = new RealService();
private static void update(){
new Thread(mm).start();
}
}
In the Service class:
public class RealService implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
// Do something
}
}
You're question is not really clear here, but I would suggest reading about TimerTask in Java
You could use a socket to listen for incoming requests, the server can spawn a new thread each time there is a request. Once the thread completes, you should intimate the client.
You could read about how a concurrent server works.
Related
I have a class say MessageListener class. That has a method startListening() which listens on the Multicast IP and Port to receive message in an infinite loop:
public class MainClass {
public static void main(String args[]) {
MessageListener listener = new MessageListener();
listener.startListening(); // Started ONLY ONce for the entire application
}
}
public class MessageListener implements MessageReceiver{
public void startListening(MessageReceiver receiver) {
new Thread("Worker thread") {
#Override
public void run() {
// TODO Auto-generated method stub
while(true) {
//MulticastSocket receive - receives byte[]
messageReceived(byte[]);
}
}}).start();
}
public void messageReceived(byte[] data) { // Interface Method
new Message().handleMessage(data);
}
}
public class Message() {
MessageHeader messageHeader;
MessageBody messageBody;
public void handleMessage(byte[] data) {
messageHeader = new MessageHeader();
messageHeader.parseHeader(data); //subsequent messages interleave the thread here?
//extract msgbody from data
messageBody = new MessageBody();
messageBody.parseMessageBody(); //subsequent messages interleave the thread here?
}
}
I have above structure of classes. startListening() is called ONLY once at the start of the application. My assumption is the startListening() creates ONE worker thread (for the entire app) in addition to main thread and all the methods messageReceived(), handleMessage(), parseHeader(), and parseMessageBody() are all called in this one worker thread and hence these methods are entirely running in single worker thread and when new message arrives from the MulticastSocket, the methods starting from messageReceived() should run sequentially like a single threaded application.
But the method access is interleaving between the incoming messages. Say for instance, while first message is accessing parseHeader(), second message also accesses parseHeader().
I could not sync everything into like one single worker thread access unless I make the method calls as “static synchronised” to make it lock on the class instance otherwise with object synchronisation, obviously the message would be having independent access with different objects.
Is there a way I can make this work like a Single worker thread access for one message till it completes or make the method access sequentially between methods without static synchronized method modifiers?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a problem when I want to run several methods not in the main thread. I created a class extends from Runnable and put all my tasks there. There are a lot of tasks actually. Then in the main thread I created a new instance of Thread and passed my runnable class as a parameter, but what I got is that the run method is the only code which executed in the thread, and if call any method inside the runnable class it will execute in the main thread instead of the new thread.
Example:
public class ConnectionManager implements Runnable {
#Override
public void run() {
login();
}
public void login() {
//Login Logic
}
public void sendMessage() {
//Send Message Via TCP Connection
}
public void updateInfo() {
//Update Information
}
public void logOut() {
//LogOut Logic
}
}
Now I wanted to call any of these methods in another thread, so I did this:
public class Login implements SomeInterface {
private Thread thread;
private ConnectionManager connection;
public void main(String[] args) {
connection = new ConnectionManager();
thread= new Thread(connection);
thread.start(); // This will execute the run method and the login process works fine.
}
#Override
public void someCallback() {
connection.sendMessage();//this call is not executed and block the main thread !!
}
}
What am I supposed to do to run all my methods in another thread without making a new thread for each method?
You should split your logic
public class Logger implements Runnable {
#Override
public void run() {
// login logic here;
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//Send Message Via TCP Connection
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//Update Information
}
}
public class MessegeSender implements Runnable {
#Override
public void run() {
//LogOut Logic
}
}
And then in some client:
Runnable logger = new Logger(credentials);
Executors.newSingleThreadExecutor().execute(logger);
Well this is how threads work in java. One possibility is to use Actors in java. You will have to download the Akka framework here:http://akka.io/downloads/.
Actors works by messages, they act in a separate process and are even driven messages. In other words depending on the message you send to the actor it will process a corresponding method.
Check in the following link for instances: http://doc.akka.io/docs/akka/snapshot/java/untyped-actors.html
The method run equivalent in java actors is onReceive().
And to send a message to the actor, myActor.tell(...)
Hope this helps you!!!!
Well, that is the way threads work in Java. When You call connection.sendMessage() Your method just treats ConnectionManager and runs it's code. You need to execute Your method in another threads run(), or it will not run. Perhaps You need a way to comunicate with Your thread to make it execute a method in run() or just explore the possibilities that Future objects give You?
That's how does Runnable or Multithread handling work.
You should never call the run() directly and only this function and other function calls inside this function are executed in the new thread.
Basically your Runnable class should only contains one public function: the run() and you should not call it directly...
I suggest you to put other functions in their own classes. As you can see the workflow is not continuous, sendMessage() is not called directly after login() (otherwise you can do it inside run() and don't need that someCallback()).
Otherwise what should that new thread supposed to do in the time between? block and wait for sendMessage()? That's not a good design. So you should start a new thread for sendMessage().
I don't know how to solve this problem I hope that you can help me.
Behind Server side I have this:
class Baza0 implements Runnable{
anotherclass arraylist_handle = new anotherclass();
public method1(string s1){uses methods figured in arraylist_handle)
public run(){
while(true){
Socket s = s.accept();
if(s==NULL) continue;
//there I'm starting another thread that handles client connection
}
}
public static void main(){
Baza0 baza0 = new Baza0();
Thread t = new Thread(baza0);
}
}
Connected clients sends Strings by socketserver feature to client handler. How can I send this string from client handler to the method1 as parameter? It must use the only one Baza0 object, because of the ArrayList that must be common for all the clients.
EDIT
can someone tell me why something like Baza0.baza0.method1() won't work?
EDIT2
Look what I did!
I've made in Class Baza0 an static variable:
static Baza0 baza1;
and in main method I've started an Baza0 object:
Baza0 baza0 = new Baza0();
after this run the method that makes baza1 = baza0.
now from client handler I have access to method, by:
Baza0.baza1.method1(param);
It does work! :D ...don't know why.
If you are using the arraylist only for reading, then all the child threads are free to access it concurrently;
if the threads want to modify the list, then the list must be thread-safe;
if the modification involves many steps (reading and writing), then you must use synchronized blocks within which a "transaction" with the list happens.
Pass a Baza0 reference to Client Handler thread which can be used for calling method1.
public method1(string s1){
synchonized(arrayList){
//list operation
}
}
...
while(true){
Socket s = s.accept();
if(s==NULL) continue;
new Thread(
new WorkerRunnable(
clientSocket, this).start();
}
....
public class WorkerRunnable implements Runnable{
public WorkerRunnable(Socket socket,Baza0 ba){
this.socket = socket;
this.baza =ba;
}
public void run(){
...
this.ba.method1(...);
}
}
Your client thread must have a reference to that ArrayList - directly or (better) indirectly. Simplest way to do this is to pass Baza0 instance (this) to the client thread:
public class Client implements Runnable {
private final Baza0 baza;
public Client(Baza0 baza) {
this.baza = baza;
}
public void run() {
//...
baza.method1("Some string");
}
}
When you create your Client thread simply pass this:
new Thread(new Client(this)).start();
Important thread safety issue: method1() has to be synchronized or your ArrayList must be thread-safe.
I'd say what #Marko Topolnik said. Also I have a book Java Concurrency In Practice (that right now is not responding to me :-() or a link that led me to the book, in the blog The Java Specialists for handling thread issues. The book has examples of all queues, concurrent, synchronized lists, ways to implement code to do several things, etc, and all pretty straight forward, an example and a few paragraphs of every subject.
I need to run a task inside a RMI service and it needs an event listener implemented for it. Right now when I pass the EventListener over RMI it does execute the call however the callback method of the Listener is not being invoked and it remains in the wait state. How should I get this to work?
public class MyEventListener implements Serializable, ABCEventListener {
private static final long serialVersionUID = -4686421592620210489L;
private boolean registrationCompleted = false;
public boolean getRegistrationCompleted(){
return registrationCompleted;
}
#Override
public void onSomethingDiscovered(Agent agent) {
System.out.println("Added agent "+agent.toString()+" to the set \n");
}
#Override
public void onDiscoveryComplete() {
this.registrationCompleted = true;
System.out.println("Discovery process completed. \n");
}
}
Here is where I pass the eventlistener to the RMI service 'ds'
MyEventListener myEL = new MyEventListener();
ds.discoverAsync(val, myEL);
waitForRegistration();
.
.
private void waitForRegistration() {
try{
while(!dcev.getRegistrationCompleted()){
System.out.println("Please wait...");
Thread.sleep(15000);
}
}catch(InterruptedException e){
logger.error("InterruptedException raised while waiting for registration",e);
e.printStackTrace();
}
}
The problem is that because your event listener is serializable the data fields of your event listener get sent across the wire and a new object created on the server side. The method is called on this copy of your event listener. This makes perfect sense for data objects, but for the likes of event listeners doesn't work as you want your client code to get the call.
I believe you can make this work if your event listener extends RemoteObject. If you do this, instead of your object being copied, it will be exposed as an RMI service when you call the server. The server instead of getting a copy of your object, will get a proxy to your event listener. The call to the event listener will result in an RMI call in the reverse direction to call your event listener.
See Passing Remote Objects in the RMI guide for more details.
I have two classes. In Class1 I have a thread and in Class2 I have to pause/lock that thread which will be started immediately after the login. In my scenario, after the login (which is implemented in Class2) the Thread has to be made wait for some more additional login and getting data from DB. Please let me know how to control the Thread running in the other class from different class.
Class1:
public class Class1{
Class2 cls2 = new Class2();
cls2.logon();
// login which will start the thread in the Class2 as well
// Please suggest what should be done here
// DB realated stuff need be done here
// Have to unlock/resume the thread in Class2
}
Class2:
public class Class2{
public void receiveMessage(String str){
new StringProcessor(str);
}
public class StringProcessor implements Runnable {
//do some stuff but have to wait for the DB related stuff in Class1
}
public void logon(){
//Will create/logon the connection and the message will be start arriving
}
}
Actually after login there will be TCP/IP connection to receive the messages. The method receiveMessage() will be called whenever the message arrives. But I have to pause that
Cheers,
Sakthi. S
There are several approaches.
The wrong one is to use Thread.suspend/resume/destroy since they are deprecated and deadlock-prone.
You can either...
Implement your own signaling mechanism by using Object.wait, Object.notifyAll.
Use the Semaphore class or any other class in java.util.concurrent that suits your needs.