Below method runs on main thread in 'Controller' class. It sends request packet to server to get device list.
public List<Device> getDeviceList(){
networkServer.sendMsg(deviceListReqPacket);
//wait till response returns. ???
}
This method runs on another thread in 'Server' class which reads data from server.
private void readDeviceList() {
// read packet from socket
List<nwkDeviceInfo_t> listdevice = networkServerDriver.getDeviceLists(packet);
}
}
What can i do to make getDeviceList() method wait until, readDeviceList() method construct listDevice.And get the listDevice object? Im a little bit confused. Am i trying something not possible or am i doing in a completely wrong way?
If your instances (of the above classes) run on the same JVM but in different threads, use one of the blocking queues that come with Java.
If they communicate over a network (e.g. HTTP and such) seems like the read would block until the write is done (and indeed received on the other side). So in that case, you already have the behaviour you want.
Related
For my Code it is necessary to call multiple asynchronous Requests from the same client to a Thrift Service.
So I am using a Non blocking Server and Asynchronous Clients (see the code below) to allow asynchronous Calls, which means the execution of the code continues after the first call of the "checkForPrime()" Method, which I call on the Thrift Service.
Now this seems to work with only executing one call. If I make a second asynchronous call right after, I get the following error message:
Client is currently executing another method:
Interfaces.PrimeCheck$AsyncClient$checkForPrime_call
at
org.apache.thrift.async.TAsyncClient.checkReady(TAsyncClient.java:78)
at
Interfaces.PrimeCheck$AsyncClient.checkForPrime(PrimeCheck.java:110)
at ThriftClient.main(ThriftClient.java:40)
I need a smart solution to allow for multiple calls, but it has to be from the same client. Any suggestions are welcome. Please dont hesitate if you need further information.
org.apache.thrift.protocol.TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();
TAsyncClientManager manager;
TNonblockingSocket socket;
AsyncClient client;
try {
manager = new TAsyncClientManager();
socket =new TNonblockingSocket("localhost", 4711);
client = new AsyncClient(factory, manager, socket);
client.checkForPrime(5, resultHandler);
client.checkForPrime(7, resultHandler);
Thread.sleep(100);
} catch (IOException e2) ....
to allow asynchronous Calls, which means the execution of the code continues after the first call of the "checkForPrime()" Method,
Not quite. Asynchronous only means that the call is completed asynchronously and you don't have to wait for the completion until necessary.
It does not imply that you can use the same client to do another parallel request. Some implementations may support this but the current implementation does not.
Multiple outstanding calls require some bookkeeping, otherwise you will get lost with the responses:
call 1 made --->
call 2 made --->
response arrives <----
response arrives <----
Now, what call does the first response belong to: call 1 or call 2? Hard to say, it could be either one. Without more information a multi-call client would have a hard time trying to correlate the data.
The TAsyncClientManager handles that by restricting clients to allowing only one pending call at a time.
it is necessary to call multiple asynchronous Requests from the same client
Why do you think it is necessary?
The client is only a mediator, a means of transport. If you send two emails, do you require the emails follow the exact same path across the interwebs? No, because the relevant information the other side (server) should rely on is in the message content, not in the transport level.
If, however, you need to store data at the client, you should store it in a dedicated place outside of the client instance. Either way, the fact that we deal with one or two client instances should not really matter.
I'm currently working on an android project that is a sort of P2P application (no central server, IP addresses are entered manually). I've already sorted out how two devices are able to connect to each other, but what I seem to be having trouble figuring out is the best way to send data back and forth with a socket.
Right now, I've got two separate threads, one for sending data, and one for receiving data so that neither attempt blocks the other. My receiving thread checks the output stream, looking for an int until one exists. The int is a flag for the type of data being sent, and depending on that flag, the application prepares to grab the rest of the data, it's all predictable.
My problem comes in when trying to set up the sending thread. I was originally going to have it so that a call on the Sender object (an extension of Thread) would simply send the all the data needed, but realized that doing that didn't actually function within the thread.
Instead, I changed it so that the thread constantly runs and checks for a flag that determines the data going to be sent. A function is called from the UI thread, which prepares the data as class members, and then sets the flag, where it is then "picked up" by the thread and sent off to the other device. However, I realized this would take up a really unnecessary amount of processor time since the loop would be checking the flag over and over.
I'm just wondering what the proper way to do this is since android doesn't allow network operations on the UI thread. Would I have to rewrite the Sender object to create a new thread every time it sends a message?
The Sender thread can be halted via wait(). The Thread can be later resumed by sending it a notify().
An short example for the sender would be:
synchronized(this){
wait();
}
synchronized(sender){
sender.notify();
}
Edit: Obviously, in the above case "this" and "sender" refer to the same Object (the Sender Thread).
Edit2: Clarification where you need to add those statements. Given your description i assume you have something similiar to the following
public void run(){
while(alive){
// synchronized(this){
if (getFlags()!=null){
//send data
setFlags(null);
}
// wait();}
}
}
in your Sender class. With the synchronized and wait you can keep the Thread from consuming all available cpu resources from a core.
Additionally you will need to modify the calling Thread. You will have add the following:
public void handleEvents(..) {
// process the event
// determine what to send
// synchronized(sender) {
sender.setFlags(mydata);
// sender.notify();}
}
Note: If you modify data here that gets accessed in the sender thread you will need to move the synchronized statement further up as this will block the current thread. If the sender blocks too long you might consider queuing the data (e.g. by having Lists of Objects instead of just Objects) and checking a boolean flag before entering the synchronized block.
I am building a server in java that communicates with several clients at the same time, the initial approach we had is the the server listens to connections from the clients, once a connection is received and a socket is created, a new thread is spawned to handle the communication with each client, that is read the request with an ObjectInputStream, do the desired operation (fetch data from the DB, update it, etc.), and send back a response to the client (if needed). While the server itself goes back to listen to more connections.
This works fine for the time being, however this approach is not really scalable, it works great for a small amount of clients connected at the same time, however since every client spawns another thread, what will happen when there are a too many clients connected at once?
So my next idea was to maintain a list of sorts that will hold all connected clients (the socket object and some extra info), use a ThreadPool for to iterate through them and read anything they sent, if a message was received then put it in a queue for execution by another ThreadPool of worker threads, and once the worker has finished with its task if a response is required then send it.
The 2 latter steps are pretty trivial to implement, the problem is that with the original thread per client implementation, I use ObjectInputStream.readObject() to read the message, and this method blocks until there is something to read, which is fine for this approach, but I can't use the same thing for the new approach, since if I block on every socket, I will never get to the ones that are further down the list.
So I need a way to check if I have anything to read before I call readObject(), so far I tried the following solutions:
Solution 1:
use ObjectInputStream.available() to check if there is anything available to read, this approach failed since this method seems to always return 0, regardless of whether there is an object in the stream or not. So this does not help at all.
Solution 2:
Use PushbackInputStream to check for the existence of the first unread byte in the stream, if it exists then push it back and read the object using the ObjectInputStream, and if it doesn't move on:
boolean available;
int b = pushbackinput.read();
if (b==-1)
available = false;
else
{
pushbackinput.unread(b);
available = true;
}
if (available)
{
Object message= objectinput.readObject();
// continue with what you need to do with that object
}
This turned out to be useless too, since read() blocks also if there is no input to read. It seems to only return the -1 option if the stream was closed. If the stream is still open but empty it just blocks, so this is no different than simply using ObjectInputStream.readObject();
Can anyone suggest an approach that will actually work?
This is a good question, and you've done some homework.... but it involves going through some history to get things right. Note, your issue is actually more to do with the socket-level communication rather than the ObjectInputStream:
The easiest way to do things in the past was to have a separate thread per socket. This was scalable to a point but threads were expensive and slow to create.
In response, for large systems, people created thread pools and would service the sockets on threads when there was work to do. This was complicated.
The Java language was then changed with the java.nio package which introduced the Selector together with non-blocking IO. This created a reliable (although sometimes confusing) way to service multiple sockets with fewer threads. In your case through, it would not help fully/much because you want to know when a full Object is ready to be read, not when there's just 'some' object.
In the interim the 'landscape' changed, and Java is now able to more efficiently create and manage threads. 'Current' thinking is that it is better/faster and easier to allocate a single thread per socket again.... see Java thread per connection model vs NIO
In your case, I would suggest that you stick with the thread-per-socket model, and you'll be fine. Java can scale and handle more threads than sockets, so you'll be fine.
I have implemented an service that runs in a seperate process.
This service contains a separate thread where i have a socket connection.
This thread has a run() where it is continuously sending data to the port.
My problem is after triggering the run() in the thread i don't get any contact with it anymore, i can see in the program that have open the socket that it consciously sends the data but the idea was that i while it is running i could change data that it sends for an example time.
here is my run in the external thread:
public void run()
{
if(run)
{
// Team and player names message is sent when entering in a game
setBaseMessage();
SendMessageToCOMPort(base_message + CalculateCRC(base_message));
sleep(); // waits for 100 ms
}
}
Anyone have any idea what might be wrong ?
I did not quite get your problem. It seems that you want to run a separate thread in your service which does some socket communication. Furthermore you want to be able to influence the data the thread is sending using the socket.
I have implemented an service that runs in a seperate process.
First of all, android services aren't running in a separate process or thread by default. Therefore, to run long running operations you have to develop multithreading by your self using Java threading and implementing the run method as you have done it.
Threads of a single process share the same memory. Therefore, to influence what the socket thread is doing, you can use data structures like a queue or a list which are shared among the threads. For example, you could apply the producer-consumer pattern. The producer passes data to a shared queue. The consumer consumes the data from the queue and processes it. However, be aware that you have to synchronize the access to the shared queue.
I hope I was able to clarify the issue and give you some advice to solve the issue.
Can anyone please tell me how to create a server and client (both) in a single file?
I searched the net and came to know that it is possible using the threads. I am not familiar with threads. I am trying to implement a peer to peer application. At some point, the peer has to behave as server and client. Can anyone please give a sample code or direct me to a good source?
Put simply, threads are parallel workflows that execute your code. So if you have two instances of threads, you can have one of them execute method A, and one of them execute method B, and both will occur concurrently. The art and science of writing concurrent code is very advanced and takes a long while to master.
However it's very easy to begin. For each piece of code you want to run separately, you create a class extending Thread, and put the code to be run in the overridden run() method. In your case, that could be a class Client extends Thread and class Server extends Thread. Then, from the code initiating the threads (maybe your public static void main() method?) you instantiate both classes, and execute their start() method. Note that start() returns immediately; the code in run() then executes in concurrency. So
a.start();
b.start();
would actually return immediately and then both a and b are running in parallel.
Read this post. This post uses a Java UDP Server and Client code which connects with a Python UDP Client and Server code.
You can make use of Java UDP Server and Client code.