Basically I have a ServerSocket listener , on new incoming connection the program executes a thread to serve it , after the thread finishes , the program doesn't continue
this is the listener
client = listenSocket.accept();
new HandleConnection(client);//HandleConnections extends thread and start
//method is called in the constructor
counter++;
System.out.println("Number of clients served : " + counter);
this is the thread
public HandleConnection(Socket client) {
this.client = client;
this.start();
}
public void run() {
try {
in = new BufferedReader(new InputStreamReader(
client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
handler();
System.out.println("Ending Thread !");
} catch (IOException e) {
//System.out.println("socket closed");
e.printStackTrace();
}
}
the message "Ending Thread !" is executed normally , but the counter++ and the following println statement are never executed
the message "Ending Thread !" is executed normally , but the counter++ and the following println statement are never executed
So if new HandleConnection(client); actually starts a new thread (which you should not do in a constructor, see below), then the counter++ should immediately be executed and the "Number of clients... message printed. Any chance the message is appearing above the "Ending Thread!" message in your logs? Typically it takes some time to start the actual thread so the caller will continue to execute before the run() method is entered.
Other comments about your code:
As #MarkoTopolnik mentions, you need to close the input and output streams in your run() method. finally clauses are a required pattern there.
You should never call Thread.start() in an object constructor because of Thread race condition issues around object construction. See: Why not to start a thread in the constructor? How to terminate?
Instead of extending Thread you should consider implementing Runnable and doing something like:
new Thread(new HandleConnection(client)).start();
Event better than managing the threads yourself would be to use an ExecutorService thread-pool for your client handlers. See this tutorial.
The typical way to do this is to perform something like this:
ServerSocket listener = new ServerSocket(3030); //Create a new socket to listen on
try
{
//While we are running, if a client connects
//accept the connect and increment the client ID
while (true)
{
new udSocketServer(listener.accept()).start();
}
}
finally //Gracefully close
{
listener.close(); //Close socket object
}
You could then call the shared variable 'counter' in the thread constructor. If you need more than this, let me know and I will edit.
But in reality you need a little more code for us to answer.
Related
Following is the code (JAVA) that accepts a client socket connection and assigns a thread to each connection.
ServerSocket m_ServerSocket = new ServerSocket();
while (true) {
java.util.Date today = Calendar.getInstance().getTime();
System.out.println(today+" - Listening to new connections...");
Socket clientSocket = m_ServerSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread( clientSocket);
cliThread.start();
}
Suppose 5 clients are connected, hence 5 threads are running.
client 1: threadId 11
client 2: threadId 12
client 3 :threadId 13
client 4 :threadId 14
client 5 :threadId 15
Suppose one of the clients sends a message "kill-client1" , I to wish end client 1's connection and kill the thread with Id 11, something like this :
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
while (running) {
String clientCommand = in .readLine();
if (clientCommand.equalsIgnoreCase("Kill-client1")) {
// end the connection for client 1 & kill it's corresponding thread 11
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
How can I achieve this ?
Just keep track of all client sockets and/or handling threads.
Map<Integer,Socket> clients=new HashMap<>();
while (true) {
java.util.Date today = Calendar.getInstance().getTime();
System.out.println(today+" - Listening to new connections...");
Socket clientSocket = m_ServerSocket.accept();
clients.put(generateNewClientId(),clientSocket);
ClientServiceThread cliThread = new ClientServiceThread( clientSocket);
cliThread.start();
}
And then if you simply do
{
if (clientCommand.equalsIgnoreCase("Kill")) {
Socket socket=clients.get(idToShutDown);// get required id somehow (from request??)
socket.close();
}
}
This will close given socket resulting in breaking in.readLine() in handling thread thus finishing thread.
If you keep track of threads, you can set "interrupt" flag and probe it in while condition so your handling thread will be able to finish work gracefully.
You could do that by storing your Threads into a thread-safe map (as it will be accessed by several threads concurrently) using the thread id as key
// Map that will contain all my threads
Map<Long, ClientServiceThread> threads = new ConcurrentHashMap<>();
// Add to the constructor the instance of the class that manage the threads
ClientServiceThread cliThread = new ClientServiceThread(this, clientSocket);
// Add my new thread
threads.put(cliThread.getId(), cliThread);
cliThread.start();
Then when a kill is launched
String clientCommand = in.readLine().toLowerCase();
if (clientCommand.startsWith("kill")) {
main.interrupt(Long.valueOf(clientCommand.substring(4).trim()));
}
Then in the main class your method would look like:
public void interrupt(long threadId) {
// Remove the thread from the map
ClientServiceThread cliThread = threads.remove(threadId);
if (cliThread != null) {
// Interrupt the thread
cliThread.interrupt();
}
}
Finally you will need to make your class ClientServiceThread sensitive to interruptions
try {
...
while (!Thread.currentThread().isInterrupted()) {
// My code here
}
} finally {
clientSocket.close();
}
Just terminate the loop:
while (running) {
String clientCommand = in .readLine();
if (clientCommand.equalsIgnoreCase("Kill")) {
running = false;
}
}
or:
while (running) {
String clientCommand = in .readLine();
if (clientCommand.equalsIgnoreCase("Kill")) {
break;
}
}
And don't forget to close the socket in finally block.
To stop the current thread, you close the socket, and return from the run() method:
if (clientCommand.equalsIgnoreCase("Kill")) {
clientSocket.close();
return;
}
EDIT:
To close another thread, you can, for example
share a thread-safe map of clientID-Thread entries between threads. When a new client connects, you store the Thread started for this client in this map
when a Kill-client1 command comes in, you get the Thread corresponging the "client1" key from the map, and call ìnterrupt() on this thread.
in each thread (for example, the client1 thread), at each iteration of the loop, you check what the value of Thread.currentThread().isInterrupted(). If it's true, then you close the connection, remove the thread from the shared map, and return from the run() method.
The key point is that you never kill another thread. You always request a thread to stop by interrupting it, and the thread checks the value of its interrupt flag to decide when and how it must stop.
I'm making a simple chat program using sockets, and I have an ArrayList to store active objected classes with sockets and usernames for each connected client, and inside those classes it checks if the socket is still open, and calls for its self to be joined if it is not.
Server file kick code:
public synchronized void kick(ClientThread client){
try{
output.printLine("kicking " + client.getUsername());
clients.remove(client);
output.printLine("removed " + client.getUsername());
}catch(Exception e){
e.printStackTrace();
}
output.printLine("kicked ");
}
This is what is called by the client object if its socket is closed.
clients being the ArrayList which stores the clients
client being the class object which I want to join, the client object extends Thread
public void run(){
while(true){
try{
Thread.sleep(10);
if(isValid()){
/*bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
if(bufferedReader.ready()){
lastMsg = bufferedReader.readLine();
sendMessage("Hello");
bufferedReader.close();
}*/
}else{
output.printLine(this.getUsername() + " connection closed");
break;
}
}catch(Exception e){
e.printStackTrace();
}
}
server.kick(this);
try {
join();
} catch (InterruptedException e) {
e.printStackTrace();
}
output.printLine("joined " + getUsername());
}
This is the run function from the client object, at the bottom is the code which is run when the socket is not connected, it breaks from the loop and should join its self, however it hangs on joining its self. The client is removed from the ArrayList properly but no matter what i do i cannot get the thread to join.
This cannot work. To join a thread means waiting until it died. If you wait for yourself to die, you will wait forever, because as long as you wait you cannot die.
if the socket is still open, and calls for its self to be joined if it is not.
A thread cannot call for itself to be joined. If a thread wants to quit then it just returns from the run() method. Other threads that are waiting for that thread to die can call thread.join() on it. But as #Vampire pointed out, for a thread to call this.join() will mean that it is waiting for itself to finish but it never will because it is waiting for itself to finish. Joinception indeed.
but no matter what i do i cannot get the thread to join.
I think the question here is what are you trying to achieve. If you want the thread to finish then just return from the run() method. If you are trying to notify other threads that you are finishing then they should do the join-ing.
I am reading a UDP feed and I want the thread to attempt to restart if their is a failure. I think I have written my class correctly but would like someone to look over and see if there is something missing or I have written something that won't get the job done. In my catch clause I attempt to restart the thread every 6 seconds for 10 attempts. Is this a good solution, will it work?
class UDPReader extends Thread
{
private Thread t;
private final String ip, socket, queue, threadName;
private String ErrorMessage;
private final JTextArea screen;
UDPReader(String ip, String socket, String queue, String threadName, JTextArea screen) {
this.ip = ip;
this.socket = socket;
this.queue = queue;
this.threadName = threadName;
this.screen = screen;
}
public void run()
{
try {
byte[] i = null;
ipaddrConnection ipaddr = new ipaddrConnection(ip, socket);
parseUDP p = new parseUDP();
screen.append("Thread " + threadName + " running\n");
while(true)
{
i = ipaddr.getPacket();
p.parseUDP(i);
//Thread.sleep(0);
}
}
catch (IOException ex) {
Logger.getLogger(MarketDataReader.class.getName()).log(Level.SEVERE, null, ex);
ErrorMessage = "Thread " + threadName + " has failed, Attempting to Restart";
screen.append("Thread " + threadName + " has failed, Attempting to Restart\n");
Email email = new Email(ErrorMessage,"WARNING Market Data Reader Failure");
for(int i = 0; i < 10 && t.isAlive() == false; i++)
{
try {
start();
Thread.sleep(6000);
} catch (InterruptedException ex1) {
Logger.getLogger(UDPReader.class.getName()).log(Level.SEVERE, null, ex1);
ErrorMessage = "Thread " + threadName + " has failed, Contact System Administraitor";
screen.append("Thread " + threadName + " has failed, Contact System Administraitor\n");
email = new Email(ErrorMessage,"WARNING Market Data Reader Failure");
}
}
}
}
public void start()
{
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
I do not know the logic behind your thread in detail but I would make some suggestions on the design of your code.
It is not clear why inside a class derived from thread you have another thread t.
There is no need to derive from Thread (and I believe it is generally a bad practice). It is common to rather implement Runnable interface and then construct a new thread using it.
.
class UDPReader implements Runnable {
...
}
and then instantiate a thread like this:
Thread t = new Thread(new UDPReader());
As a rule, if a thread fails, it terminates... It does not look good that a failed thread "recreates" itself. The better solution would be to provide a Thread.UncaughtExceptionHandler and in the code that creates your thread analyze failing conditions and restart you thread if needed.
In general, not to mess up, in concurrent programming you have to clearly distinguish the logic of a thread and external logic that manages this thread (its start/interruption/termination). I think, this is what you did not do in your code.
I'd say that it is a very bad design to restart a thread from inside of the same thread.
If you need a 'supervisor' thread then you should most likely create another 'supervisor' thread that would create and start the 'worker' thread whenever it finds out that 'worker' thread is down.
One thing you should be aware of is that when you catch an exception in Java, the program (or thread) does not terminate unless you tell it too.
Therefore, if you caught your exception exactly at the command that caused it to happen - inside the loop - you would not need to run another thread. Your thread is alive and will continue to loop. All you need to do - inside the catch block - is fix things up so that the next loop can continue as usual - close and reopen streams, clear partially filled data structures, stuff like that.
Of course, if further, unrecoverable exceptions happen, you should indeed stop your thread.
I have socket server in Java and other side socket client in PHP
I want to process socket request from PHP in java in same time by multi-threading but java do it one by one , wait to finish first request and the start second one ,
here is my code in JAVA :
while (true) {
try {
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++) {
if (threads[i] == null) {
(threads[i] = new clientThread(clientSocket, threads)).start();
break;
}
}
if (i == maxClientsCount) {
PrintStream os = new PrintStream(clientSocket.getOutputStream());
os.println("Server too busy. Try later.");
os.close();
clientSocket.close();
}
} catch (IOException e) {
System.out.println(e);
}
}
class clientThread extends Thread {
public clientThread(Socket clientSocket, clientThread[] threads) {
this.clientSocket = clientSocket;
this.threads = threads;
maxClientsCount = threads.length;
}
public void run() {
int maxClientsCount = this.maxClientsCount;
clientThread[] threads = this.threads;
try {
in = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
URL aURL = new URL(RecivedURL);
// start out put
System.out.println("host = " + aURL.getHost());
// end out put
the BOLD line is example of my output , but I want to start output of multi started request in same time in same time .. JAvA wait to finish a request in one time for my code ..
I don't see why you'd want more than two threads here.
If you want to process request one by one, you might spawn just one thread that just listens the requests and immediately responds to it by sending a "processing" or a "check back later" message. (call this a listener thread)
if a client is sent a "processing" response the connection is kept alive and another thread is spawned that responds to the client with the actual processed result of request. (call this a processing thread).
You could make the listener thread send a keep alive message to the client in queue or you could ask it to check back after a set period of time with a request. You could make the listener thread more sophisticated by setting up queues to decide when to subsequently respond to clients who were sent "check back later" message
From implementation POV, your main thread could be your listener thread and it could spawn a processing thread when it's time to process a request.
I assume that it's executed so fast that the last request is finished before the next one can be accepted.
For debug purposes try to add:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
into the run method so you can easier check if it's really not running in parallel.
I am trying to read input from a socket line by line in multiple threads. How can I interrupt readLine() so that I can gracefully stop the thread that it's blocking?
EDIT (bounty): Can this be done without closing the socket?
Without closing the socket:
The difficult problem isn't the BufferedReader.readLine, but the underlying read. If a thread is blocked reading, the only way to get it going is to supply some actual data or close the socket (interrupting the thread probably should work, but in practice does not).
So the obvious solution is to have two threads. One that reads the raw data, and will remain blocked. The second, will be the thread calling readLine. Pipe data from the first the second. You then have access to a lock than can be used to wakeup the second thread, and have it take appropriate action.
There are variations. You could have the first thread using NIO, with a single thread instance shared between all consumers.
Alternatively you could write a readLine that works with NIO. This could even take a a relatively simple single-threaded form, as Selector.wakeup exists and works.
Close the socket on the interrupting thread. This will cause an exception to be thrown on the interrupted thread.
For more information on this and other concurrency issues, I highly recommend Brian Goetz's book "Java Concurrency in Practice".
Sorry for being over 6 years late ;-) I had a need for some interruptible readLine when reading from the keyboard, for a simple hobby console application. In other words, I couldn't "close the socket".
As you may know, System.in is an InputStream that apparently already does some buffering (you need to press Enter]). However, it seems to be suggested to wrap it in a BufferedReader for better efficiency, so my input is from:
BufferedReader consoleIn = new BufferedReader(new InputStreamReader(System.in));
The other thing one might have discovered is that BufferedReader.readLine() blocks until input is provided (even if the thread is interrupted, which seems to only end the thread once readline() gets its input). It is however possible to predict when BufferedReader.read() will not block, by calling BufferedReader.ready() == true. (However, == false does not guarantee a block, so beware.)
So I have incorporated the above ideas into a method that reads the BufferedReader character by character, checking in between each character if the thread has been interrupted, and also checks for end-of-line, at which point the line of text is returned.
You may find this code useful, pass the consoleIn variable as declared above. (Criticism may be welcomed too...):
private String interruptibleReadLine(BufferedReader reader)
throws InterruptedException, IOException {
Pattern line = Pattern.compile("^(.*)\\R");
Matcher matcher;
boolean interrupted = false;
StringBuilder result = new StringBuilder();
int chr = -1;
do {
if (reader.ready()) chr = reader.read();
if (chr > -1) result.append((char) chr);
matcher = line.matcher(result.toString());
interrupted = Thread.interrupted(); // resets flag, call only once
} while (!interrupted && !matcher.matches());
if (interrupted) throw new InterruptedException();
return (matcher.matches() ? matcher.group(1) : "");
}
... And in the thread that is calling this, catch the exceptions and end the thread appropriately.
This was tested in Java 8 on Linux.
I was playing around with this recently (using Scala), and I didn't like the accepted answer of closing the socket and getting an exception.
Eventually I discovered that it's possible to call socket.shutdownInput() in the interrupting thread to get out of the readLine call without an exception. I make this call in a SIGINT handler so that I can clean up and close the socket in the main thread.
Note, that the equivalent exists for the outputstream with socket.shutdownOutput()
you can design a Timer class around the read() block.
you need to set a timeout for your timer.
on timeout just interrupt your thread.
Without closing the socket, no question the best solution with the least overhead is to simply avoid using the blocking read methods until the BufferedReader is ready, or a timeout is reached.
public String readLineTimeout(BufferedReader reader, long timeout) throws TimeoutException, IOException {
long start = System.currentTimeMillis();
while (!reader.ready()) {
if (System.currentTimeMillis() - start >= timeout)
throw new TimeoutException();
// optional delay between polling
try { Thread.sleep(50); } catch (Exception ignore) {}
}
return reader.readLine(); // won't block since reader is ready
}
If you want to use readLine on a server socket within a client-server tcp architecture, for instance, you can use setSoTimeout(int timeout) of java.net.Socket.
From the Socket#setSoTimeout(int timeout) Documentation:
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid.
public class MainApp {
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(10);
ServerSocket serverSocket = new ServerSocket(11370);
Socket clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(2000);
executorService.execute(new ReadingThread(clientSocket));
// ... some async operations
executorService.shutdown();
}
}
public class ReadingThread implements Runnable {
private final Socket clientSocket;
public ReadingThread(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
BufferedReader socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String readInput = null;
while (!Thread.currentThread().isInterrupted()) {
try {
readInput = socketReader.readLine();
} catch (SocketTimeoutException e) {
continue;
}
}
// operations with readInput
}
}
The main application implements a server socket which listens to connections and has a thread pool. If an incoming client communication is accepted, then a new Thread from the pool is assigned and the run function is invoked in ReadingThread (can be adjusted to allow multiple threads).
On the socket used for communicating to the client the property setSoTimeout(int timeout) has been set. Therefore if readLine does not return within the specified timeout a SocketTimeoutException is thrown.
You can check in a loop whether the ReadingThread has been interrupted by the main application, and if so stop reading from the socket.
When the buffered reader is being used to read the input stream from a socket then you can achieve this by having the read call timeout. Once this timeout is triggered you will be able to check if your thread should be stopped. To do this call setSoTimeout on the socket. The read call will then have a SocketTimeoutException and you can use that to stop the thread.
#Override
public void run() {
running = true;
try {
socket.setSoTimeout(1000); // This will determine how quick your thread responds to the shutdown call
var inputStream = socket.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
} catch (IOException e) {
Logger.error("IOException while setting up input stream");
Logger.error(e);
return;
}
StringBuilder stringBuilder = null;
while (running) {
try {
int singleChar = bufferedReader.read();
// Do something with the data
} catch (SocketTimeoutException e) {
// SocketTimeoutException is expected periodically as we do setSoTimeout on the socket,
// this makes the above read call not block for ever and allows the loop to be interrupted
// cleanly when we want to shut the thread down.
Logger.trace("Socket timeout exception");
Logger.trace(e);
} catch (IOException e) {
Logger.error("IOException while reading from socket stream");
Logger.error(e);
return;
}
}
}
public void stopThread() {
running = false;
try {
bufferedReader.close();
} catch (IOException e) {
Logger.error("IOException while closing BufferedReader in SocketThread");
Logger.error(e);
}
}
Answer found here: Any way of using java.nio.* to interrupt a InputStream#read() without closing socket?
I think that you might have to use something other than readLine(). You could use read() and at every loop iteration check to see if the thread was interrupted and break out of the loop if it was.
BufferedReader reader = //...
int c;
while ((c = reader.read()) != -1){
if (Thread.isInterrupted()){
break;
}
if (c == '\n'){
//newline
}
//...
}
A sketch for a solution might be this: NIO provides methods for nonblocking IO, so you have to implement something called Foo that uses nonblocking NIO on the socket end but also provides a InputStream or Reader interface on the other end. If the BufferedReader enters its own read, it will call Foo, which will call Selector.select with read intent. select will either return indicating the presence of more data or it will block until more data is available.
If another thread wants to unblock the reader, it must call Selector.wakeup and the selector can return gracefully by throwing an exception the by BufferedReader.
The socket should be still open after that.
Variation A: call Selector.select(timeout) to do busy polling light.