I have a Runnable that watches for data to send out UDP as well as to send a keep alive every 10 seconds. The process is taking 100% CPU. I tried setting the thread to low priority but didn't seem to make any difference.
private Runnable keepAliveRunnable = new Runnable() {
long nextSend = 0;
byte[] sendData;
#Override
public void run() {
if(DEBUG)
System.out.println("Starting keepAlive.");
while (socket != null) {
synchronized (socketLock) {
try {
sendData = sendQueue.poll();
if (sendData != null) {
socket.send(new DatagramPacket(sendData, sendData.length,
InetAddress.getByName(Main.ipAddress), 10024));
} else if (nextSend < System.currentTimeMillis()) {
if(DEBUG && nextSend < System.currentTimeMillis())
System.out.println("Update keepAlive.");
// Send /xremote
socket.send(new DatagramPacket(("/xremote").getBytes(),
("/xremote").getBytes().length,
InetAddress.getByName(Main.ipAddress), 10024));
nextSend = System.currentTimeMillis() + keepAliveTimeout;
// Send /info
socket.send(new DatagramPacket(("/info").getBytes(),
("/info").getBytes().length,
InetAddress.getByName(Main.ipAddress), 10024));
}
} catch (IOException e) {
e.printStackTrace();
if(!e.getMessage().contains("Socket closed")) {
e.printStackTrace();
}
}
}
}
System.out.println("keepAliveRunnable ended.");
}
};
Make sendQueue a LinkedBlockingQueue, and use poll timeouts.
You are busy waiting, which essentially forces your app to keep running the same logic over and over instead of giving the CPU back to the system.
Don't count on your own implementation of checking the time, that is unreliable and can result in what you're seeing. Instead, use blockingQueue.poll(10, TimeUnit.SECONDS), which automatically handles returning the CPU to the system.
I made a few other changes to your code; I put the duplicated packet construction code in a separate method, and I wrapped the synchronization of the socket only when the socket is actually being used. Notice how much cleaner it is when you let the queue do the work for you.
while(socket != null) {
try {
sendData = sendQueue.poll(10, TimeUnit.SECONDS);
if (sendData != null) {
sendPacket(sendData);
} else {
sendPacket("/xremote".getBytes());
sendPacket("/info".getBytes());
}
} catch (IOException e) {
e.printStackTrace();
if (!e.getMessage().contains("Socket closed")) {
e.printStackTrace();
}
}
}
And here's sendPacket:
private static void sendPacket(byte[] data) throws UnknownHostException, IOException {
// Note, you probably only have to do this once, rather than looking it up every time.
InetAddress address = InetAddress.getByName(Main.ipAddress);
DatagramPacket p = new DatagramPacket(data, data.length, address, 10024);
synchronized(socketLock) {
socket.send(p);
}
}
You should add a Thread.sleep() at the bottom of your while loop, to slow down your loop. As is, you're busy-waiting and churning the CPU while you wait for the nextSend time to be reached. Thread.sleep() will actually pause the thread, allowing other threads and processes to use the CPU while this one sleeps.
Sleeping for a 10th of a second (100 milliseconds) should be a good amount of time to sleep between iterations of your loop, if your goal is to actually do work every 10 seconds.
There are more advanced techniques for dispatching work every so often, like ScheduledExecutorService, which you could also consider using. But for a small application the pattern you're using is fine, just avoid busy waiting.
I think rather than polling your sendqueue, its better to use semaphore signal and wait.
When a packet is inserted in sendqueue, call semaphore signal.
Use semaphore wait instead of call to sendqueue.poll().
I assume you have separate threads for pushing popping data from sendqueue.
This is standard consumer producer problem. https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem
After digging through my code, I had realized that over time I had whittled down the number of processes sending data to 1 (duh) so I really didn't need the runnable as I could just send the data directly. I also set up a separate runnable and used ScheduledExecutor. I thought I would just put that here for other to see. Durron597's code is a little prettier but since I'm only sending two packs now I decided to just put the code together.
// In main
pingXAir();
private void pingXAir() {
System.out.println("Start keepAlive");
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(keepAliveRunnable, 0, 5, TimeUnit.SECONDS);
}
private Runnable keepAliveRunnable = new Runnable() {
#Override
public void run() {
synchronized (socketLock) {
try {
if (DEBUG)
System.out.println("Update keepAlive.");
// Send /xremote
socket.send(new DatagramPacket(("/xremote").getBytes(),
("/xremote").getBytes().length,
InetAddress.getByName(Main.ipAddress), 10024));
// Send /info
socket.send(new DatagramPacket(("/info").getBytes(),
("/info").getBytes().length,
InetAddress.getByName(Main.ipAddress), 10024));
} catch (IOException e) {
e.printStackTrace();
if (!e.getMessage().contains("Socket closed")) {
e.printStackTrace();
}
}
}
}
};
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 SocketChannel configured for read only SelectionKey.OP_CONNECT | SelectionKey.OP_READ
Profiler shows runChannel is the most CPU consuming method and actually it is reasonable because it's infinite loop which calls method selector.select() all the time, but on the other hand I have dozens of such connections and it kills CPU.
Is there a possibility to decrease CPU load and in the same time do not miss any incoming message?
public void runChannel() {
while (session.isConnectionAlive()) {
try {
// Wait for an event
int num = selector.select();
// If you don't have any activity, loop around and wait
// again.
if (num == 0) {
continue;
}
} catch (IOException e) {
log.error("Selector error: {}", e.toString());
log.debug("Stacktrace: ", e);
session.closeConnection();
break;
}
handleSelectorkeys(selector.selectedKeys());
}
}
Unsunscribe from OP_CONNECT - select() won't block if you're subscribed to OP_CONNECT and connected.
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.
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've a memory leak problem on java Socket Object communication.
this is my send thread.
// create a new thread to send the packet
#Override
public synchronized void run() {
if(!genericSocket.isConnected()){
if(logger.isEnabled())
logger.logMessage(PFLogging.LEVEL_WARN, "Socket is close");
return;
}
int retry = 0;
boolean packetSent = false;
synchronized (objWriter) {
while ((retry < RETRY) && (!packetSent) && (genericSocket.isConnected())) {
try {
objWriter.writeObject(bean);
objWriter.flush();
// Try until the cache is reset and the memory is free
/*
boolean resetDone = false;
while(!resetDone) {
try {
objWriter.reset();
resetDone = true;
} catch (IOException r) {
Thread.sleep(1);
}
}
*/
// No error and packet sent
continuousError = 0;
packetSent = true;
} catch (Exception e) {
continuousError++;
if(logger.isEnabled())
logger.logMessage(PFLogging.LEVEL_ERROR, "Continuous Error [" + continuousError + "] sending message [" + e.getMessage() + "," + e.getCause() + "]");
// control the number of continuous errors
if(continuousError >= CONTINUOUS_ERROR) {
if(logger.isEnabled())
logger.logMessage(PFLogging.LEVEL_WARN, "I close the socket");
genericSocket.disconnect();
}
// next time is the time!
retry++;
}
}
}
}
the cache, when i sent about i packet per ms grow and grow!
if i add the commented part the cache is clean but when i need to send an async long message (about 3000 char) i see that the other message are lost!
There's another way to clean the cache without reset it??
ObjectOutputStream.reset() is not avoidable as it is the only means of clearing local hash tables, you can refer java source code for ObjectOutputStream for details of what happens in reset(), or else you will get OutOfMemoryError eventually
But you can very well implement a function like
private void writeObject(Object obj, ObjectOutputStream oos) throws IOException
{
synchronized(oos)
{
oos.writeObject(obj);
oos.flush();
oos.reset();
}
}
However you must ensure that all writes to ObjectOutputStream happens through this method.
the only solution i find is, first of starting a sending thread, to check if the thread pool is empty and in that case i reset the output stream.
I run the software all this night to check this.
Thanks all!
Matteo
I would use ObjectOutputStream.reset() periodically to clear the object cache for the stream.
You could even use it after sending every object. ;)
ciao :),
after ObjectOutputStream.flush() you can saftely use ObjectOutputStream.reset()
unless you are using the objWriter somwhere in another thread without using the synchronized (objWriter) statement.
In this case the best way IMHO is to use the objWriter in a thread, it will send object from a syncornized queue (see Queue sub-class http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Queue.html, for example http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html) that is filled from the other thread (remeber to use object.clone(), because the objcet itself isn't syncornized it can be modified by other thread while you are writing it or is in queue! if you clone it your clone will be a safe copy).
That way you don't need synchronized statment because data-flow between thread and ObjectOutputStream is already synchronized, and you will be less error-prone