How can I implement threads in this scenario? - java

I haven't got any code at the moment but I have a situation where I will be implementing an Java application onto a wireless sensor. There can only be one main method.
There will be multiple other wireless sensors that can connect to my sensor. My sensor needs to do a calculation based on thhe information provided to me by the other sensors. Each sensor can choose whether or not they want to participate in the calculation. Every 1 second, my sensor does a calculation.
So basically, what I need is to listen for incoming sensors, provide them with a thread to interact with, and retrieve the information from each sensor.
My question is, in my application, how do I listen for incoming sensors (blocking call) and also free my application to carry out its calculations?

From a high level, this is what your application will do
==Main Thread==
start socket
Start processing thread
accept an incoming connection (this will cause the thread to block until a connection occurs)
start new thread to handle socket (handler thread) (alternatively use a thread pool, but that is more complicated)
return to 3
==Handler Thread==
Receive open socket from main thread
Save data coming in from socket to be given to processing thread
Finish and close socket
==Processing Thread==
Wait 1 second
Process data retrieved from step 2 of Handler Thread
Return to 1

You need another thread that receives the information of all the communication threads. You should look at the utilities in java.util.concurrent such a BlockingQueue that let threads pass data to one another thread-safely.
Most of all you should read a lot about multi-threading: it is not a trivial topic.

This will get you started. Add error/exception checking/handling as necessary.
public class Test {
static class WorkTask42 implements Runnable {
public void run() {
// background work
}
}
public static void main(String... args) throws Exception {
// repeat for each background task
WorkTask42 wt = new WorkTask42();
Thread a = new Thread(wt);
a.setDeamon(true);
a.start();
}
}

Related

Can a Thread in an ExecutorService call a method on a seperate thread?

I have a socket server that uses an ExecutorService to create a new thread for each new socket. I also have a static instance of a class that makes database calls that all threads use.
My server is used for online chess matches. When a user makes a move, the move is sent to the server and an entry is made in the DB with general information about the move (including the ID of the match). Every 10 seconds or so, if the match's other client also has an active socket to the server, it will ask the server to fetch all new data about the match.
It works, but as you can imagine gets pretty inefficient if a non-trivial number of players are connected. What I want is a way for a thread to peek into the thread pool and find another thread based off an ID (The ID of the client for whom the thread is used), then call a method on that thread to send a message to the opposing player.
I've been looking all over, and I've had no luck. Is such a thing possible? If it is, is it advisable? Even if it's a bit risky code-wise, I'm willing to take extra steps to mitigate the risk for the enormous resource-saving benefits.
Like I said in my comment, your question is confusing; if all you're trying to do is to notify the opponent when a player makes a move, the simplest implementation is to use a BlockingQueue. The Javadoc even has code examples, so it should be fairly easy to implement. In your case, whenever a player makes a move, you put an item in the queue, that the consumer picks up and notifies the opponent that is participating in the same game. You don't need to mess with low level thread constructs, and if you're even thinking of finding threads based on ids from a pool, you're doing it all wrong.
The BlockingQueue would work, but it involves busy wait, so I'm not a big fan of it. Instead, you can use the Observer design pattern; the JDK already has support for this. Following is an example that I made up:
public class Main extends Observable implements Observer {
private final int numCores = Runtime.getRuntime().availableProcessors();
private final ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(numCores);
public Main() {
addObserver(this);
}
public static void main(String[] args) throws InterruptedException {
new Main().execute();
}
private void execute() {
for (int i = 0; i < 5; ++i) {
this.setChanged();
this.notifyObservers(i);
try {
Thread.sleep(1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
#Override
public void update(Observable o, Object arg) {
System.out.printf("Received notification on thread: %s.\n", Thread.currentThread().getName());
executor.submit(() -> System.out.printf("Running in thread: %s, result: %s.\n",
Thread.currentThread().getName(), arg));
}
}
Received notification on thread: main.
Running in thread: pool-1-thread-1, result: 0.
Received notification on thread: main.
Running in thread: pool-1-thread-2, result: 1.
Received notification on thread: main.
Running in thread: pool-1-thread-3, result: 2.
Received notification on thread: main.
Running in thread: pool-1-thread-4, result: 3.
Received notification on thread: main.
Running in thread: pool-1-thread-5, result: 4.
Last but not the least, if you really want to take it up a notch, use messaging. You didn't mention if you're using a framework (again, lack of information on your part), but Spring supports messaging, so does Akka, Play and Camel.
You may create the ExecutorService supplying your own ThreadFactory able to create your istantiate your own class that extends Thread and has a reference to the ThreadFactory itself. The ThreadFactory should trak all created Thread and be able to identify them by their ID. Such a way, each Thread will be able to query the ThreadFactory for some ID.

How to handle tcp inputstream correctly - Java/Android

I'm creating an android application that needs a permanent TCP-Connection to a Server.
I've created a Service that establishes the Connection and listens for incoming Bytes on the Inputstream (The service runs in the background).
public class TCPServiceConnection extends Service{
//variables......
//...............
public void onCreate() {
establishTCPConnection():
}
The first 4 incoming bytes symbolize the message-length of a complete Message.
After reading a complete Message from the Inputstream into a separate buffer, I want to call another Service/Asynctask in a separate Thread that analyses the Message. (The service should continue listening for further incoming messages).
public handleTCPInput() {
while(tcp_socket.isConnected()) {
byte[] buffer = readCompletemessagefromTCPInputstream;
calltoAnotherThreadToanalyzeReceivedMessage(buffer);
}
//handle exceptions.......
}
Is there an existing Messagequeue-system in Android/Java that already handles the multi-access onto my separated byte[] buffer ?
To implement this I suggest you start a handler thread which will continuously read from the input stream.
As soon it has read the incoming message, it passes it to main thread using handler.
For eg. handler.sendMessage()
Now since this processing is not a heavy operation you can decide main/UI thread to process this information or you can start a async task to do it.

Two threads concuration in main programm

I have program (MAIN) that has two thread that communicates with com port (COM) and TCP session (TCP).
If main (MAIN) program need info from TCP and COM modules it sends request message R (tR and cR). When threads have answer they send back answer A (tA and cA). I have problem, when I send reguest to COM (cR) and without getting answer from it have answer from TCP- tA. COM R-A should be somehow isolated from TCP interruption. How to solve this problem using JAVA 1.4 ?
UPD. On tA event MAIN initiates cR - request to COM port. Main can initiate request to COM by itself. I would like avoid to have second question to COM port without getting answer from first one.
UPD2. Actually whole system looks like picture below. cR might be started by tA or by uR. And cA can answer to TCP via tR or to UI via uA.
Following scenarios are correct
uR->cR->cA->tR-tA->cR->cA->uA
cA->tR->tA->cR
uR->cR->cA->uA
I'm getting troubles when two requests goes to COM at the same time.
cA->tR->tA->cR
uR->cR
I would like to allow new request only in case when COM returns answer to first caller.
As I understand correctly you have 2 threads in main method. 1 thread is interacting with with TCP and another with COM. Right?
If this is the case than what you can do is you can let handle thread 1 to handle all TCP request/response and thread 2 to handle all COM request/response. And the main thread is not aware of this. Until the time both thread finish their job independently the main threads wait and once both thread are done with their job, Main thread can resume its work. hence the communication of COM and TCP is completley separate. you can use Threads "join()" method here.
Did I answer your question?
You don't have to use multiple threads. Just read the request from the socket, synchronously process the request by communicating over the COM port, and then write the response over the socket.
There may be reasons to use multiple threads, though. For example, perhaps you want to be able to respond to socket requests with a time-out error if the COM port doesn't respond fast enough, but the serial port library you are using doesn't support a time-out configuration. In that case, you'll have to clarify your requirements. What do you want to happen if another request is received from the socket, but the COM thread is still stuck handling a previous request? You could wait, respond with an error immediately, etc.
Create a single-thread ExecutorService. Whenever you need to interact with the COM port, whether the request originates from the socket or from the main program itself, submit the task to this service. This will ensure that serial communications won't be interleaved with competing requests.
The basic idea here is to allow only one thread to use the COM port, consuming a queue of tasks produced by various other threads.
Here is one example that can explain your system. Here i have made a environment of caller receiver. Until caller not end with his or her statement receiver can not start with saying anything or respond to caller.
Caller.java
public class Caller implements Runnable {
MaintainACall call;
Caller(MaintainACall me)
{
call=me;
new Thread(this,"Mr X").start();
}
public void run()
{
String a[]={"Hello how r u", "I'm in vadodara"};
for(int i=0;i<2;i++)
{
call.sayHello(a[i]);
}
}
}
Receiver.java
public class Reciver implements Runnable {
MaintainACall call;
Reciver(MaintainACall call)
{
this.call=call;
new Thread(this,"Mr Y").start();
}
public void run()
{
call.Wtshesay();
}
}
MaintainACall.java
public class MaintainACall {
String say;
boolean valueSet=false;
synchronized String Wtshesay()
{
while(!valueSet)
try
{
wait();
}
catch(InterruptedException ie)
{
System.out.println(ie);
}
System.out.println("I have heared "+say);
valueSet=false;
notify();
return say;
}
synchronized void sayHello(String msg)
{
while(valueSet)
try
{
wait();
}
catch(InterruptedException ie)
{
System.out.println(ie);
}
say=msg;
valueSet=true;
System.out.println("She says "+say);
notify();
}
}
MainClass.java
public class MainClass {
public static void main(String arg[])
{
MaintainACall my=new MaintainACall();
new Caller(my);
new Reciver(my);
}
}

Call a method of all parallel Class Threads

I have a question for you.
I have multiple Threads runnings of a class called ServerThread. When an specific event happens on ANY of those threads, I want to call a method of every other thread running in parallel.
public class ServerThread implements Runnable {
private TCPsocket clientSocket;
public ServerThread(Socket comSocket){
clientSocket = new TCPsocket(comSocket);
}
#Override
public void run(){
boolean waiting = true;
Message msg;
try{
while(waiting){
msg = clientSocket.getMessage();
shareMessage(msg);
}
}catch(Exception e){
ErrorLogger.toFile("EndConnection", e.toString());
}
}
public void shareMessage(Message msg){
clientSocket.sendMessage(msg);
}
}
I am talking about this specific line
shareMessage(msg);
which I would like to be called on every thread/instance
-- so that a message is sent to every client (in all tcp connections)
I've tried with synchronized but either I'm not using it well or that is not what I am looking for.
Another thing that might work is keeping a class with an static member which is a list of those tcpconnection objects and then do some loop in all every time.
Thanks for your help and time.
Edited with one possible solution
*Add an static array as a member of the class and add/remove objects of same class (or tcp sockets would also work)
private static ArrayList<ServerThread> handler;
...
handler.add(this);
...
handler.remove(this); //when client exists and thread stops
*Then create a method that iterates for each connection, and make it synchronized so that two threads won't interact at the same time. You may want to implement synchronized on your message sending methods as well.
public void shareMessage(Message msg){
//this.clientSocket.sendMessage(msg);
synchronized (handler){
for(ServerThread connection: handler){
try{
connection.clientSocket.sendMessage(msg);
} catch(Exception e){
connection.clientSocket.closeConnection();
}
}
}
}
First: synchronized is required to prevent race conditions when multiple threads want to call the same method and this method accesses/modifies shared data. So maybe (probably) you will need it somewhere but it does not provide you the functionality you require.
Second: You cannot command an other thread to call a method directly. It is not possible e.g. for ThreadA to call methodX in ThreadB.
I guess you have one thread per client. Probably each thread will block at clientSocket.getMessage() until the client sends a message. I don't know the implementation of TCPsocket but maybe it is possible to interrupt the thread. In this case you may need to catch a InterruptedException and ask some central data structure if the interrupt was caused because of a new shared message and to return the shared message.
Maybe it is also possible for TCPsocket.getMessage() to return, if no message was received for some time, in which case you would again have to ask a central data structure if there is a new shared message.
Maybe it is also possible to store all client connections in such a data structure and loop them every time, as you suggested. But keep in mind that the client might send a message at any time, maybe even at the exact same time when you try to send it the shared message received from another client. This might be no problem but this depends on your application. Also you have to consider that the message will also be shared with the client that sent it to your server in the first place…
Also take a look at java.util.concurrent and its subpackages, it is likely you find something useful there… ;-)
To summarize: There are many possibilities. Which one is the best depends on what you need. Please add some more detail to your question if you need more specific help.

Trying to figure out how to make a simple network game Need some help

I'm writing a simple card reading game.
The idea is that the server will start at game board position 1. Then it will wait until it gets a HTTP message from all the players or a time out. The reply will be for the information of the current board position. Thus if a client ends up sending 2 messages, it will get two replies with the same game bored id.
Each time it get a connection from a client, a thread will be sent out to process the message and it will wait for the next connection.
PROBLEM: the messages are process on a serpent thread. If all the players have replied with a message. What would be the best way to tell the main thread to go to the next board pos?? Maybe I would just have to make it single thread? But then I'm afraid that a bug could freeze the server.
Then there is the issue of the time out.
One idea I had was to set a timeout on the socket, so if no connection was made, it would always exit, and then could check for a time out or if all the players have sent a message.
This is my first attempt at a network game, I'm assuming there are a lot of ways to do this.
Ted
What I do is have a main Server class, with a thread for each client. The thread is added to an ArrayList of Threads representing each client.
You can then have the Server class iterate over the list and check for a value, such as hasMessage. If each one is true, then continue the game.
Here is some cheap code that does it:
//...Somewhere in the Server
ArrayList<Thread> clients = new ArrayList<Thread>();
public void addClient() {
clients.add(new ClientThread());
}
public boolean checkForMessages() {
for(Thread t : clients)
if(!t.hasMessage)
return false;
return true;
}
The ClientThread class handles talking to each client, with each one on its own thread.
Here's some ~code that might help.
// use an atomic integer so all threads can count their moves
AtomicInteger moveCounter = new AtomicInteger();
// main thread is in a loop
long timeoutMillis = System.currentTimeMillis() + MOVE_TIMEOUT_MILLIS;
while (moveCounter.get() < NUMBER_OF_CLIENTS) {
synchronized (moveCounter) {
// wait a second
moveCounter.wait(timeoutMillis - System.currentTimeMillis());
}
if (System.currentTimeMillis() >= timeoutMillis) {
// we timed out, break
break;
}
}
// now go ahead and process the move ...
Each client handler would do:
// read the move from the client ...
// store the move somewhere in the server...
moveCounter.decrementAndGet();
// exit
You probably should be using the Executors.newCachedThreadPool() or another one of the thread pools to fork a handler for each of your client connections.
Hope this helps.

Categories

Resources