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.
Related
I have a message stream, where messages comes which I need to process and then store them in database. In Java, I've written polling code which polls stream and consumes messages every 20 seconds.
This is done inside an infinite for-loop, like below:
for (;;) {
try{
//1. Logic for polling.
//2. Logic for processing the message.
//3. Logic for storing the message in database.
Thread.sleep(20000 - <time taken for above 3 steps >);
} catch(Exception E){
//4. Exception handling.
}
}
This logic runs as expected and the stream is polled, but once in a while it hits an exception or something goes wrong and polling stops.
I want to have a mechanism, that as soon as polling stopped, let's say this for loop is not running for 60 seconds, I should receive a mail or ping.
What is the best way to invoke a method if this for loop is not running for 60 seconds?
I am thinking like, each for-loop execution will ping a heartbeat, and when that heartbeat pinging not received from for-loop then a mail sending is invoked.
There are two different reasons why polling stops making progress, and each needs a different approach:
If the logic throws a Throwable other than an Exception, for instance an Error, the catch does not match, and execution will leave the for-loop, and likely reach the thread's UncaughtExceptionHandler, the default implementation of which logs the exception to System.err and terminates the thread. To prevent this, you should catch Throwable rather than Exception.
The second possibility is that some step in your logic doesn't terminate, for instance due to an infinite loop, a deadlock, waiting for I/O operations, or whatever. In this case, you'll want to take a thread dump to see where the thread is stuck. You can automate this as follows:
class Watchdog {
final Duration gracePeriod;
final Thread watchedThread;
volatile Instant lastProgress;
public Watchdog(Duration gracePeriod) {
this.gracePeriod = gracePeriod;
watchedThread = Thread.currentThread();
everythingIsFine();
var t = new Thread(this::keepWatch);
t.setDaemon(true);
t.start();
}
public void everythingIsFine() {
lastProgress = Instant.now();
}
void keepWatch() {
while (true) {
var silence = Duration.between(lastProgress, Instant.now());
if (silence.compareTo(gracePeriod) > 0) {
System.err.println("Watchdog hasn't seen any progress for " + silence.toSeconds() + " seconds. The watched thread is currently at:");
for (var element : watchedThread.getStackTrace()) {
System.err.println("\tat " + element);
}
}
try {
Thread.sleep(gracePeriod);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
while you can use as follows:
public class Test {
void step() throws Exception {
System.in.read();
}
void job() {
var snoopy = new Watchdog(Duration.ofSeconds(2));
for (;;) {
try {
step();
snoopy.everythingIsFine();
Thread.sleep(1000);
} catch (Throwable t) {
System.err.println(t);
}
}
}
public static void main(String[] args) throws Exception {
new Test().job();
}
}
once the grace period elapses, the WatchDog will print something like:
Watchdog hasn't seen any progress for 2 seconds. The watched thread is currently at:
at java.base/java.io.FileInputStream.readBytes(Native Method)
at java.base/java.io.FileInputStream.read(FileInputStream.java:293)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:255)
at java.base/java.io.BufferedInputStream.implRead(BufferedInputStream.java:289)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:276)
at stackoverflow.Test.step(Test.java:48)
at stackoverflow.Test.job(Test.java:55)
at stackoverflow.Test.main(Test.java:65)
I have my multithread web server and now i wish to implement a thread pool, however even after looking about it i don't get how can i do it in my code :(
Could someone help me get it better?
I really need to understand how what i read can be used here, because i don't see the connection and how that works.
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class WebServer {
static class RequisicaoRunnable implements Runnable {
private Socket socket;
RequisicaoRunnable(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
//System.out.println("connection from " + socket.getInetAddress().getHostName());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//System.out.println("READING SOCKET...");
String str = in.readLine();
String[] arr = str.split(" ");
if (arr != null && arr.length > 2) {
while(!str.equals("")) {
//System.out.println(str);
str = in.readLine();
}
if (arr[0].equals("GET")) {
//System.out.println("REQUESTED RESOURCE: " + arr[1]);
String nomeArquivo = arr[1];
if (arr[1].startsWith("/")) {
nomeArquivo = nomeArquivo.substring(1);
}
if (nomeArquivo.equals("")) {
nomeArquivo = "index.html";
}
File f = new File(nomeArquivo);
if (f.exists()) {
FileInputStream fin = new FileInputStream(f);
socket.getOutputStream().write("HTTP/1.0 200 OK\n\n".getBytes());
byte[] buffer = new byte[1024];
int lidos;
do {
lidos = fin.read(buffer);
if (lidos > 0) {
socket.getOutputStream().write(buffer, 0, lidos);
}
} while (lidos > 0);
fin.close();
} else {
socket.getOutputStream().write("HTTP/1.0 404 Not Found\n\n".getBytes());
socket.getOutputStream().write("<html><body>HTTP/1.0 404 File Not Found</body></html>\n\n".getBytes());
}
} else {
socket.getOutputStream().write("HTTP/1.0 501 Not Implemented\n\n".getBytes());
}
}
socket.close();
} catch (IOException e) { }
}
}
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("waiting connections....");
while (true) {
Socket socket = serverSocket.accept();
RequisicaoRunnable req = new RequisicaoRunnable(socket);
new Thread(req).start();
}
}
}
Idea behind the Thread pool is that create a specified number of threads at start and then assign task to them. Alternatively removing headache of creating threads each time.
I was implemented it a little some days ago, here is what I done.
Create some threads at start they share a request queue
Threads are constantly looking for queue and when a request come one
of the thread dispatch the request and perform action
The Queue will be synchronized 3.
Here are some queue methods
Queue#add(); //add the socket at the end
Queue#removeFront();//remove socket
Queue#isEmpty();//boolean if queue is empty
Queue#size(); //return size of queue
Queue#getMaxSize();//get maximum allowed size for queue
Your Request processing runnable
public class Processor implements Runnable {
private Queue<Socket> requests;
private boolean shut;
Processor(Queue<Socket> requests) {
this.requests = requests;
shut = false;
}
#Override
public void run() {
while(!shut) {
if(requests.isEmpty()) {
try{
Thread.sleep(#rendomeTimemill);
} catch(InterruptedException e){}
}else {
Socket skt = Queue.removeFront();
try {
//System.out.println("processing request from " + socket.getInetAddress().getHostName());
//do you want
} catch (Exception e) {
} finally {
if(skt != null) {
try{ skt.close(); skt = null; } catch(IOException ex){}
}
}
}
}
}
public void stopNow() {
shut = true;
Thread.interrupt();
}
}
in your main thread
create a queue to put requests
//start your server socket
Queue<Socket> requests = new Queue<Socket>();
Start worker thread pool
Precessor []workers = new Processor[NUM_WORKER];
for(int i=0;i<NUM_WORKER; i++) {
worker[i] = new Processor(requests);
Thread th = new Thread(worker[i]);
th.strat();
}
in request listening
//while loope that run forever
// accept socket
if(requests.size() == requests.getMaxSize()) {
socket.getOutputStream().write("HTTP/1.0 505 Error\n\n".getBytes());
socket.getOutputStream().write("<html><body>Try again</body></html>\n\n".getBytes());
socket.close();
} else {
requests.add(socket);
}
when you want to shout down server
for(int i=0;i<NUM_WORKER; i++) {
worker[i].stopNow();
}
Note: My concern was not the HTTP headers, so i m not specific, but you must implement the complete HTTP header e.g. Content-type, Content-length etc.
JDK might be a good place to start
An Executor or ExecutorService should is what you're looking for. Reading material:
http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html
The examples in there are pretty complete I think, but here's an example using the code you posted:
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("waiting connections....");
ExecutorService pool = Executors.newCachedThreadPool();
while (true) {
Socket socket = serverSocket.accept();
RequisicaoRunnable req = new RequisicaoRunnable(socket);
pool.execute(req);
}
}
We create an executor service that is backed by a cached thread pool. You can swap this out for any type of pool you like by changing the type of executor service you get from Executors:
http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html
In the example I've given we use a cached thread pool which should create new threads as needed but re use old ones as they become available (finish whatever they were executing). If you look through the methods provided in that class you can create Executor services that are backed by various types of thread pool e.g. single thread, fixed number of threads, etc.
The example above should work as is, but if you want to change how the thread pool works try another thread pool type.
The cached thread pool will mean each connection will immediately be serviced, however it can create an unbounded number of threads.
on the other hand if you wanted the executor to use a blocking queue as suggested by fge you could try a fixed thread pool instead:
Executors.newFixedThreadPool(x)
you get the blocking queue for free with that.
You can use, for instance, a BlockingQueue. This is the basis for a producer/consumer scenario.
In your case:
the producer holds the server socket; it accepts new client sockets and pushes the client sockets onto the queue;
the consumers grab client sockets from the queue and process requests.
On top of all that, you can also use a bounded queue; you can try and push a new client socket to the queue; if the queue is full you can then default to a "no can't do" consumer.
Scenarios are many. There is not one answer.
OK, the idea is simple enough. You main loop currently creates a new RequisicaoRunnable object and a new Thread to run it each time it gets a connection from a client. The idea behind a thread pool is to avoid creating new Threads each time.
In the simplest version of a thread pool, you create a blocking queue, and you create and start a fixed number of worker threads before you enter your main loop. The main loop will look almost exactly the same as what you have now, but instead of starting a Thread to run each new RequisicaoRunnable, it will simply add the new object to the queue.
Your worker threads are all the same:
while (! shutdownHasBeenRequested()) {
RequisicaoRunnable requisicaoRunnable = getATaskFromTheQueue();
requisicaoRunnable.run();
}
That way, each new task (client) will be executed (handled) by the next available thread from your pool.
If this is a homework assignment then you'll pretty much want to implement what I described, filling in some details as needed.
If it's not homework, then consider using a java.util.concurrent.ThreadPoolExcecutor() instead. No point in re-inventing the wheel when there's a perfectly good wheel right there waiting to be used.
Edit: as fge said, one improvement would be to send back a quick "sorry, try again later" response when new connections are coming in faster than you can handle them. When the queue has too many pending connections in it (i.e., when you hit the limit of a BoundedQueue), that's when you know to bail out and send the "try again later" response.
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.
My android application implements data protection and working with cloud.
Application consists of UI and standalone service (runing in own process).
I'm using IPC(Messages & Handlers) to communicate between UI and service.
I have the next situation - before make some work with data i need to know about data size and data items count (i have to enumerate contacts, photos, etc and collect total information for progresses).
About problem:
When enumeration starts on the service side(it uses 4 runing threads in threadpool) my UI is freezing for several seconds (depends on total data size).
Does anybody know any way to make UI work good - without freezing in this moment?
Update:
Here is my ThreadPoolExecutor wrapper that i am using in service to execute estimate tasks(created like new ThreadPoolWorker(4,4,10)):
public class ThreadPoolWorker {
private Object threadPoolLock = new Object();
private ThreadPoolExecutor threadPool = null;
private ArrayBlockingQueue<Runnable> queue = null;
private List<Future<?>> futures = null;
public ThreadPoolWorker(int poolSize, int maxPoolSize, int keepAliveTime){
queue = new ArrayBlockingQueue<Runnable>(5);
threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);
threadPool.prestartAllCoreThreads();
}
public void runTask(Runnable task){
try{
synchronized (threadPoolLock) {
if(futures == null){
futures = new ArrayList<Future<?>>();
}
futures.add(threadPool.submit(task));
}
}catch(Exception e){
log.error("runTask failed. " + e.getMessage() + " Stack: " + OperationsHelper.StringOperations.getStackToString(e.getStackTrace()));
}
}
public void shutDown()
{
synchronized (threadPoolLock) {
threadPool.shutdown();
}
}
public void joinAll() throws Exception{
synchronized (threadPoolLock) {
try {
if(futures == null || (futures != null && futures.size() <= 0)){
return;
}
for(Future<?> f : futures){
f.get();
}
} catch (ExecutionException e){
log.error("ExecutionException Error: " + e.getMessage() + " Stack: " + OperationsHelper.StringOperations.getStackToString(e.getStackTrace()));
throw e;
} catch (InterruptedException e) {
log.error("InterruptedException Error: " + e.getMessage() + " Stack: " + OperationsHelper.StringOperations.getStackToString(e.getStackTrace()));
throw e;
}
}
}
}
Here the way to start enumeration tasks that i use:
estimateExecutor.runTask(contactsEstimate);
I must say you did not provided enough information (the part of the code you suspect as the cause..)
but from my knowledge and experience I can make an educated guess -
you are probably performing code on the UI thread (main thread) that it execution taking a while. I can also guess that this code is : querying cotacts / gallery provider for all the data..
in case you don't know - Service callback methods also been executed from the main thread (the UI thread..) unless explicitly you run them from AsyncTask / another thread, and querying content providers and processing it returned cursor for data can also be heavy operation that need to be executed from another thread for not blocking the main UI thread.
after removing the code performing this expensive queries to another thread - there is no reason you'll experience any freezing.
I'm new in Java so please forgive any obscene errors that I may make :)
I'm developing a program in Java that among other things it should also handle clients that will connect to a server. The server has 3 threads running, and I have created them in the following way :
DaemonForUI du;
DaemonForPort da;
DaemonForCheck dc;
da = new DaemonForPort(3);
dc = new DaemonForCheck(5);
du = new DaemonForUI(7);
Thread t_port = new Thread(da);
Thread t_check = new Thread(dc);
Thread t_ui = new Thread(du);
t_port.setName("v1.9--PORTd");
t_check.setName("v1.9-CHECKd");
t_ui.setName("v1.9----UId");
t_port.start();
t_check.start();
t_ui.start();
Each thread handles a different aspect of the complete program. The thread t_ui is responsible to accept asynchronous incoming connections from clients, process the sent data and send other data back to the client. When I remove all the commands from the previous piece of code that has to with the t_ui thread, everything runs ok which in my case means that the other threads are printing their debug messages.
If I set the t_ui thread to run too, then the whole program blocks at the "accept" of the t_ui thread.
After reading at online manuals I saw that the accepted connections should be non-blocking, therefore use something like that :
public ServerSocketChannel ssc = null;
ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(port));
ssc.configureBlocking(false);
SocketChannel sc = ssc.accept();
if (sc == null) {
;
}
else {
System.out.println("The server and client are connected!");
System.out.println("Incoming connection from: " + sc.socket().getRemoteSocketAddress());
in = new DataInputStream(new BufferedInputStream(sc.socket().getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(sc.socket().getOutputStream()));
//other magic things take place after that point...
The thread for t_ui is created as follows :
class DaemonForUI implements Runnable{
private int cnt;
private int rr;
public ListenerForUI serverListener;
public DaemonForUI(int rr){
cnt = 0;
this.rr = rr;
serverListener = new ListenerForUI();
}
public static String getCurrentTime() {
final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
return (sdf.format(cal.getTime()));
}
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName() + "\t (" + cnt + ")\t (every " + rr + " sec) # " + getCurrentTime());
try{
Thread.sleep(rr * 1000);
cnt++;
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
Obviously, I'm doing something wrong at the creation of the socket or at the use of the thread. Do you know what is causing the problem?
Every help would be greatly appreciated.
Don't use non-blocking I/O until you know you need it. Just start a new thread for every accepted socket, as well as for the accepting threads.
Problem solved :)
I looked at your suggestions and had a closer look at the code. It was a design error since I had a function that created a while(true) loop inside the constructor of DaemonForUI (and more specifically inside ListenerForUI()). It was causing the whole program to cycle through the while statement, therefore stalling every other action.
Silly mistake I must admit... :(
Thanks for all the help everyone that answered my question.
I will consider the mentioned idea of creating a new thread for every incoming connection. The duty that has to be performed for every incoming connection is not so heavy, so I thought that one single thread could do the job.