Editor's note: Sometimes the most interesting discussions begin when someone says, "This may be a stupid question, but ...." If the person asking the question has taken the time to think about the problem before asking, the question is often not stupid at all. The uncertainty points out an ambiguity in the specs, holes in the docs, or a search for how more experienced programmers might address a particular problem. From time to time, we will print one of the "(Not So) Stupid Questions" we receive and invite our readers to answer the question in the feedback section.
Remember that new people are joining the Java community all the time and may be looking for help from those with more experience. Also, those who began with Java as their first language can benefit from those coming to the community with experience in other languages. As always, answer the questions with kindness. You are also welcome to submit your questions to
This may be a stupid question, but ... "Can I have a thread that doesn't use run()?"
First Thoughts
I have a simple problem--but am surprised I don't know how to answer it.
I have a class/object A running in one box that sends out messages/events. I write a second Java application, B, that runs on another box and wants to receive these messages/events from A--to do so, this B class has to implement an interface (call it A_Listener) of three methods (F1, F2, and F3) to receive these messages/events. But application B has lots of other things it has to do, other than just getting messages/events from A. In fact, its main work is something else, and its main method and other code does all this other stuff. Application B wants to receive A's messages/events asynchronously, letting the rest of its code do its usual work. So I wanted to write a Java thread that I could add to application B--to leave the rest of application B code the same, doing its main usual job--but have this extra thread in B receiving the messages and events from A.
But the only way I know how to write a Java thread is to mainly do the work of the thread in a run method. But the job that the thread has to do should be done in the three methods (F1, F2, and F3) that implement the A listener interface. How do you reconcile that with the fact that the work of the thread has to be done via the run method--while unfortunately, the reception of the messages and events has to be implemented by the explicit methods of the interface?
How can both the run method do the work of receiving the messages/events from A? (And the methods F1, F2, and F3 really do this, too.) The only way you can get this stuff from A is to get it in the methods F1, F2, and F3! I can't figure how to make a Java thread, with a run method, do this! Sorry to be repetitive--but I want to be clear what the problem is:
Can you write a thread in Java that doesn't use run, but uses other interface methods?
Thread is just another class.
2007-11-25 20:39:10 pbssundar
[Reply | View]
(Stupid answer)
Threads are just another class in java!
You can call do all that you want to do to a normal class. However, if you want to have your own thread to do something without affecting the calling thread - then you do a start() on your thread - this inturn calls the run() method which is the entry-point to your class (similar to the main() method being the entry point to a program).
From this entry point do whatever you want to do - create objects, call methods, etc. So that the stuffs here are executed on your new thread.
For instance, you can create your Object and call the 3 methods in sequence within the run() method.
public void F1() {
executorService.execute(new Runnable() {
public void run() {
b.F1();
}
});
}
public void F2() {
executorService.execute(new Runnable() {
public void run() {
b.F2();
}
});
}
public void F3() {
executorService.execute(new Runnable() {
public void run() {
b.F3();
}
});
}
}
I assume you have some sort of listener list in class A:
public class A {
private void fireF1() {
for (A_Listener listener : listeners) {
listener.F1();
}
}
public void addListener(A_Listener listener) {
listeners.add(listener);
}
// ...
fireF1();
}
And then all you need to do is to add a BProxy as a listener to the A class:
BProxy proxy = new BProxy(new B(), Executors.newFixedThreadPool(poolSize));
a.addListener(bproxy);
I hope you get the idea. There are several implementation of executor service you can use directly from the package. Have a look and see if you can't find one that suits your needs.
Use Concurrrency API?
2007-11-02 05:36:32 alexanderschunk
[Reply | View]
Isnt this is a typical example for using Javas concurrency API? You have a remote application and i assume you are using Java RMI for receiving and sending method calls. If you want to make it thread safe you might use
Java concurrency API.
Use an InvocationHandler
2007-11-01 11:40:49 averyregier
[Reply | View]
Here is an answer to "Can I have a thread that doesn't use run()?" The architectural questions have already been addressed by other posters.
public void F1(String message) {
System.out.println("F1: " + message+" in thread "+Thread.currentThread().getName());
}
public void F2(String message) {
System.out.println("F1: " + message+" in thread "+Thread.currentThread().getName());
}
public void F3(String message) {
System.out.println("F1: " + message+" in thread "+Thread.currentThread().getName());
}
}
Some answers
2007-11-01 07:33:22 melvng
[Reply | View]
A: No, a Thread, AFAIK, _have_to_ execute code within run() (either from a subclass or the Runnable interface).
What I would do in your case:
- To send messages/events from A to B, use som Remote Procedure Call apis. The basic RMI in java would do, but you can also check out XMLRPC.
If you use RMI, then you don't need any extra threads for processing the method calls (F1,F2 and F3). The RMI framework will create it's own threads to do this.
You need to ensure that F1,F2 & F3 put the events/messages into a synchronized data structure (e.g. Vector). The class 'ArrayBlockingQueue' would also fit nicely here.
- To process the events on B, use your main() thread or create a new one.
From the sounds of it, I'd say you need to take a step back and take a look at the architecture - It sounds like you're stuck on the fact that you want it threaded by F1(), F2() and F3() and not by run().
I'm assuming here that A is running on a machine separate from the machine B is running on. I'm also assuming both are standalone java apps. This leads me to assume you're making some kind of Socket connection for communication?
I'm guessing what you're really wanting is a Thread that runs asynchronously and handles the events from A without disturbing the rest of B, but interacts with it.
I'd say you'll probably want to spawn a thread that listens for incoming events in it's run() method. Once it picks up an event message it would recognize that it's an F1, F2 or F3 event and spawn a new Thread depending on the type of event.
I'm assuming here that the event processing might take long and an F2 event could be fired while F1 is processing, and you want all the events processed on their own thread too. If you don't mind it queuing, you could forgo the extra threads and just fire off the methods you need directly.
I hope that makes sense - this would be my approach to the solution.
For what I had understood of the question, I would subscribe to cmdrdats suggestion:
1. Spawn a thread from main().
2. In that thread build the object C implementing the interface {F1,F2,F3} and make it listen to incoming calls.
3. Be careful about synchronisation when C accesses data of B.
If using RMI you can consider a bypass of 1 above, since the RMI virtual machine infrastructure would use their separate threads for interface calls. However I am not sure this is mandatory, regarding the RMI specification.
It depends ;-)
2007-11-01 06:06:38 jbarnum
[Reply | View]
It depends on the mechanics of how your listener works. Is it using RMI? Web Services? HTTP? Raw sockets?
If you're doing most of the work yourself, like with raw sockets, then there will most likely be a single entry point that you will need to listen for in your thread and then dispatch to the appropriate method (F1 / F2 / F3). If you're using something higher level like RMI, those requests come in on their own threads anyway and so the whole issue is not applicable.