How to perform with longadder - java

Hello I have an application calculate time and throwing an event according that. I would like to make my application with thread safe using longadder or whatever is suitable.
my class below;
#Autowired
EventListenerConfiguration eventListenerConfiguration;
private volatile long lastReceivedMessage = System.currentTimeMillis();
public void consume(String message) Integer partition,
(Headers.OFFSET) Long offset, Acknowledgment ack) {
lastReceivedMessage = System.currentTimeMillis();
try {
seervice.processMessage(message, ack, null);
} catch (ParseException e) {
logger.error(e.getMessage());
}
}
#Scheduled(fixedDelayString = "${listenScheduled}", initialDelay = 100000)
private void distanceBetweenLastReceivedMessageAndCurrentTime() {
long currentTime = System.currentTimeMillis() - lastReceivedMessage;
if (currentTime >= EventListenerConfiguration .getTotalMilliSecondTimeForError()) {
EventUtil.publishEvent(THROW_ERROR_EVENT, EventSeverityStatus.ERROR, EventTypeStatus.CUSTOM, null);
} else (currentTime >= EventListenerConfiguration.getTotalMilliSecondTimeForWarn()) {
EventUtil.publishEvent(THROW_WARN_EVENT, EventSeverityStatus.WARN, EventTypeStatus.CUSTOM, null);
}
}
so basicly how to convert my code without changing much to longAdder and also perform currentTime-lastReceiveMessage
Thank you

Good Evening. It appears that your issue is largely that lastReceivedMessage is a protected resource used by two threads. Whatever is running the consume method generates it, and then the Spring-Generated #scheduled thread consumes it.
Adding the volatile keyword will not prevent the code from reading the field. It will only prevent the code from caching the variable. (Read up on volatile https://www.geeksforgeeks.org/volatile-keyword-in-java/) If you want to treat the #Scheduled block as a critical region, and prevent the updating of the lastRecievedMessage until it is complete, I would recommend the following:
private volatile long lastReceivedMessage = System.currentTimeMillis();
private Semaphore resourceLock = new Semaphore(1);
public void consume(String message) Integer partition,
(Headers.OFFSET) Long offset, Acknowledgment ack) {
resourceLock.acquireUninterruptibly();
try {
lastReceivedMessage = System.currentTimeMillis();
} finally {
resourceLock.release();
}
try {
seervice.processMessage(message, ack, null);
} catch (ParseException e) {
logger.error(e.getMessage());
}
}
#Scheduled(fixedDelayString = "${listenScheduled}", initialDelay = 100000)
private void distanceBetweenLastReceivedMessageAndCurrentTime() {
long currentTime = 0;
resourceLock.acquireUninterruptibly();
try {
currentTime = System.currentTimeMillis() - lastReceivedMessage;
if (currentTime >= EventListenerConfiguration .getTotalMilliSecondTimeForError()) {
EventUtil.publishEvent(THROW_ERROR_EVENT, EventSeverityStatus.ERROR, EventTypeStatus.CUSTOM, null);
} else (currentTime >= EventListenerConfiguration.getTotalMilliSecondTimeForWarn()) {
EventUtil.publishEvent(THROW_WARN_EVENT, EventSeverityStatus.WARN, EventTypeStatus.CUSTOM, null);
}
} finally {
resourceLock.release();
}
}

Related

Efficient Timeout for a blocking operation without synchronization

I'm trying to create a timeout for a blocking operation, a InputStream.read() in the specific case, using a timeout thread without synchronization.
This is needed to avoid that a blocking operation will last forever and its aim is to achieve the best performance.
This should be a typical use case:
try(InputStream input = request.getInputStream())
{
Utils.consumeWithTimeout(input, 60000, (buffer, n) ->
{
output.write(buffer, 0, n);
checksum.update(buffer, 0, n);
});
}
where
public static void consumeWithTimeout(InputStream in, long timeout, BiConsumer<byte[], Integer> consumer) throws IOException
{
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
try(TimedOp timedOp = new TimedOp(timeout, () -> closeQuietly(in)))
{
while(true)
{
timedOp.start();
int n = in.read(buf);
timedOp.pause();
if(n <= 0)
{
return;
}
consumer.accept(buf, n);
}
}
finally
{
closeQuietly(in);
}
}
and
public static class TimedOp implements AutoCloseable
{
private Thread th;
private volatile long last = 0;
private volatile boolean paused = true;
public TimedOp(long timeout, Runnable runnable)
{
th = new Thread(() ->
{
try
{
while(!th.isInterrupted())
{
long now = System.currentTimeMillis();
if(last + timeout > now)
{
Thread.sleep(last + timeout - now);
}
else if(paused)
{
Thread.sleep(timeout);
}
else
{
runnable.run();
return;
}
}
}
catch(InterruptedException e)
{
return;
}
});
}
public void start()
{
State state = th.getState();
if(state == State.TERMINATED)
{
throw new IllegalStateException("thread is terminated");
}
if(!paused)
{
throw new IllegalStateException("already running");
}
last = System.currentTimeMillis();
paused = false;
if(state == State.NEW)
{
th.start();
}
}
public void pause()
{
paused = true;
}
#Override
public void close()
{
th.interrupt();
try
{
th.join();
}
catch(InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
do you see a problem or space for improvement?
what I tried
Suppose you need to care about 1GB data transfer, with a 8KB buffer.
can I use an ExecutorService for scheduling the read()?
No, I can't.
public static void consumeWithExecutor(InputStream in, long timeout, BiConsumer<byte[], Integer> consumer) throws IOException
{
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
ExecutorService executor = Executors.newSingleThreadExecutor();
try
{
while(true)
{
Future<Integer> future = executor.submit(() -> in.read(buf));
int n = future.get(timeout, TimeUnit.MILLISECONDS);
if(n <= 0)
{
return;
}
consumer.accept(buf, n);
}
}
catch(InterruptedException | ExecutionException | TimeoutException e)
{
// do nothing, handling in finally block
}
finally
{
closeQuietly(in);
executor.shutdownNow();
}
}
the overhead of spawning/reusing/restarting a thread for each single read is overkill.
Performance loss is unbearable.
can I use a Timer for scheduling the read()?
No, I shouldn't.
public static void consumeWithTimer(InputStream in, long timeout, BiConsumer<byte[], Integer> consumer) throws IOException
{
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
try
{
while(true)
{
Timer timer = new Timer();
TimerTask task = new TimerTask()
{
#Override
public void run()
{
closeQuietly(in);
}
};
timer.schedule(task, timeout);
int n = in.read(buf);
timer.cancel();
if(n <= 0)
{
return;
}
consumer.accept(buf, n);
}
}
finally
{
closeQuietly(in);
}
}
Timer and TimerTask are not reusable, a new instance should be created for each iteration.
Internally, Timer synchronizes on a queue of tasks, leading to unnecessary locking.
This result in a performance loss, a little thinner than using an ExecutorService, nevertheless it's not as efficient as my original implementation.

Capture Total Execution time of a parallel thread

I am using java.util.concurrent.Executors and java.util.concurrent.ExecutorService to execute parallel threads. Please let me know how to capture Time taken for complete all threads.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CallBackTest {
private static int NUM_OF_TASKS = 50;
Object result;
int cnt = 0;
long begTest, endTest;
public CallBackTest() { }
public void callBack(Object result) {
System.out.println("result "+result);
this.result = result;
}
public void run() {
ExecutorService es = Executors.newFixedThreadPool(50);
for(int i = 0; i < NUM_OF_TASKS; i++) {
CallBackTask task = new CallBackTask(i);
task.setCaller(this);
es.submit(task);
// at this point after submitting the tasks the
// main thread is free to perform other work.
}
}
public static void main(String[] args) {
new CallBackTest().run();
}
}
Create Simple Task as
public class SimpleTask implements Runnable {
AtomicLong totalTime;
public SimpleTask(AtomicLong totalTime) {
this.totalTime = totalTime;
}
#Override
public void run() {
long currentTime = System.nanoTime();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
totalTime.addAndGet(System.nanoTime()-currentTime);
}
}
// Main Pass AtomicLong to each task to capture the time taken for that thread. and sum it to the same instance. AtomicLong is thread safe.
AtomicLong totalTime = new AtomicLong(0);
long currentTime = System.nanoTime();
ExecutorService executor = Executors.newFixedThreadPool(numberofThread);
for (int i = 0; i < numberofTasks; i++) {
SimpleTask task = new SimpleTask(totalTime);
executor.submit(task);
}
executor.shutdown();
// Wait until all the threads completed.
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {}
// Calculate the time
System.out.println("Overall time"+ (System.nanoTime()-currentTime));
// Get the value from Atomic Long
System.out.println("All Threads Spent time"+ totalTime);

How do we know threadPoolExecutor has finished execution

I have a parent thread that sends messages to MQ and it manages a ThreadPoolExecutor for worker threads which listen to MQ and writes message to output file. I manage a threadpool of size 5. So when I run my program, I have 5 files with messages. Everything works fine until here. I now need to merge these 5 files in my parent thread.
How do I know ThreadPoolExecutor finished processing so I can start merging files.
public class ParentThread {
private MessageSender messageSender;
private MessageReciever messageReciever;
private Queue jmsQueue;
private Queue jmsReplyQueue;
ExecutorService exec = Executors.newFixedThreadPool(5);
public void sendMessages() {
System.out.println("Sending");
File xmlFile = new File("c:/filename.txt");
List<String> lines = null;
try {
lines = FileUtils.readLines(xmlFile, null);
} catch (IOException e) {
e.printStackTrace();
}
for (String line : lines){
messageSender.sendMessage(line, this.jmsQueue, this.jmsReplyQueue);
}
int count = 0;
while (count < 5) {
messageSender.sendMessage("STOP", this.jmsQueue, this.jmsReplyQueue);
count++;
}
}
public void listenMessages() {
long finishDate = new Date().getTime();
for (int i = 0; i < 5; i++) {
Worker worker = new Worker(i, this.messageReciever, this.jmsReplyQueue);
exec.execute(worker);
}
exec.shutdown();
if(exec.isTerminated()){ //PROBLEM is HERE. Control Never gets here.
long currenttime = new Date().getTime() - finishDate;
System.out.println("time taken: "+currenttime);
mergeFiles();
}
}
}
This is my worker class
public class Worker implements Runnable {
private boolean stop = false;
private MessageReciever messageReciever;
private Queue jmsReplyQueue;
private int processId;
private int count = 0;
private String message;
private File outputFile;
private FileWriter outputFileWriter;
public Worker(int processId, MessageReciever messageReciever,
Queue jmsReplyQueue) {
this.processId = processId;
this.messageReciever = messageReciever;
this.jmsReplyQueue = jmsReplyQueue;
}
public void run() {
openOutputFile();
listenMessages();
}
private void listenMessages() {
while (!stop) {
String message = messageReciever.receiveMessage(null,this.jmsReplyQueue);
count++;
String s = "message: " + message + " Recieved by: "
+ processId + " Total recieved: " + count;
System.out.println(s);
writeOutputFile(s);
if (StringUtils.isNotEmpty(message) && message.equals("STOP")) {
stop = true;
}
}
}
private void openOutputFile() {
try {
outputFile = new File("C:/mahi/Test", "file." + processId);
outputFileWriter = new FileWriter(outputFile);
} catch (IOException e) {
System.out.println("Exception while opening file");
stop = true;
}
}
private void writeOutputFile(String message) {
try {
outputFileWriter.write(message);
outputFileWriter.flush();
} catch (IOException e) {
System.out.println("Exception while writing to file");
stop = true;
}
}
}
How will I know when the ThreadPool has finished processing so I can do my other clean up work?
Thanks
If you Worker class implements Callable instead of Runnable, then you'd be able to see when your threads complete by using a Future object to see if the Thread has returned some result (e.g. boolean which would tell you whether it has finished execution or not).
Take a look in section "8. Futures and Callables" # website below, it has exactly what you need imo:
http://www.vogella.com/articles/JavaConcurrency/article.html
Edit: So after all of the Futures indicate that their respective Callable's execution is complete, its safe to assume your executor has finished execution and can be shutdown/terminated manually.
Something like this:
exec.shutdown();
// waiting for executors to finish their jobs
while (!exec.awaitTermination(50, TimeUnit.MILLISECONDS));
// perform clean up work
You can use a thread for monitoring ThreadPoolExecutor like that
import java.util.concurrent.ThreadPoolExecutor;
public class MyMonitorThread implements Runnable {
private ThreadPoolExecutor executor;
private int seconds;
private boolean run=true;
public MyMonitorThread(ThreadPoolExecutor executor, int delay)
{
this.executor = executor;
this.seconds=delay;
}
public void shutdown(){
this.run=false;
}
#Override
public void run()
{
while(run){
System.out.println(
String.format("[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s",
this.executor.getPoolSize(),
this.executor.getCorePoolSize(),
this.executor.getActiveCount(),
this.executor.getCompletedTaskCount(),
this.executor.getTaskCount(),
this.executor.isShutdown(),
this.executor.isTerminated()));
try {
Thread.sleep(seconds*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
And add
MyMonitorThread monitor = new MyMonitorThread(executorPool, 3);
Thread monitorThread = new Thread(monitor);
monitorThread.start();
to your class where ThreadPoolExecutor is located.
It will show your threadpoolexecutors states in every 3 seconds.

Application hangs for few minutes even after all the threads are done

I converted a working Producer/Consumer Example from Thread/Runnable to Executor/Callable/BlockingQueues and using the Poison Pill termination pattern.
If you run the program below, it will hang for few minutes even though every thread has completed.
jstack shows numerous threads blocked on a queue that is not seemingly related to the application.
"pool-1-thread-10" prio=5 tid=10b08d000 nid=0x10d91c000 waiting on condition [10d91b000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <7f3113510> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:680)
I can not figure out why the application hangs. Any help is appreciated.
Thank you
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
public class ProducersConsumers {
private LinkedBlockingQueue<Item> queue = new LinkedBlockingQueue<Item>();
private static final ExecutorService executorPool = Executors.newCachedThreadPool();
private Random randGenerator = new Random(System.currentTimeMillis());
private class Item {
private boolean done = false;
private String message;
private Item(boolean done) {
this.done = done;
}
private Item(String message) {
this.message = message;
}
public boolean isDone() {
return done;
}
public String getMessage() {
return message;
}
}
private class Producer implements Callable<Long> {
private final int id;
private Integer numOfMessages;
private Producer(int id, int numOfMessages) {
this.id = id;
this.numOfMessages = numOfMessages;
}
#Override
public Long call() throws Exception {
long totalTime = 0;
while (numOfMessages > 0) {
String message;
synchronized (numOfMessages) {
long starttime = System.nanoTime();
int msgLength = randGenerator.nextInt(20000);
StringBuilder sb = new StringBuilder(msgLength);
for (int a = 0; a < msgLength; a++) {
sb.append((char) ('a' + randGenerator.nextInt(26)));
}
message = sb.toString();
long endtime = System.nanoTime();
totalTime += endtime - starttime;
}
numOfMessages--;
queue.put(new Item(message));
}
System.out.println("-------------Producer " + id + " is done.");
queue.put(new Item(true));
return totalTime;
}
}
private class Consumer implements Callable<Long> {
private String monitor = "monitor";
private final int id;
private Consumer(int id) {
this.id = id;
}
#Override
public Long call() throws Exception {
long totalTime = 0;
while (true) {
Item item = queue.take();
if (item.isDone()) {
break;
}
synchronized (monitor) {
long starttime = System.nanoTime();
StringBuilder sb = new StringBuilder(item.getMessage());
sb = sb.reverse();
String message = sb.toString();
long endtime = System.nanoTime();
totalTime += endtime - starttime;
}
}
System.out.println("+++++++++++++Consumer " + id + " is done.");
return totalTime;
}
}
public void begin(int threadCount) throws InterruptedException, ExecutionException {
Collection<Producer> producers = new ArrayList<Producer>();
for (int i = 0; i < threadCount; i++) {
producers.add(new Producer(i, randGenerator.nextInt(5)));
}
Collection<Consumer> consumers = new ArrayList<Consumer>();
for (int i = 0; i < threadCount; i++) {
consumers.add(new Consumer(i));
}
try {
long starttime = System.nanoTime();
List<Future<Long>> producerFutureList = executorPool.invokeAll(producers);
List<Future<Long>> consumerFutureList = executorPool.invokeAll(consumers);
long producerTotalTime = 0;
long consumerTotalTime = 0;
for (Future<Long> future : producerFutureList) {
producerTotalTime += future.get();
}
for (Future<Long> future : consumerFutureList) {
consumerTotalTime += future.get();
}
long mainThreadTotalTime = System.nanoTime() - starttime;
System.out.println("producerTotalTime " + producerTotalTime);
System.out.println("consumerTotalTime " + consumerTotalTime);
System.out.println("mainThreadTotalTime " + mainThreadTotalTime);
System.out.println("Difference " + (producerTotalTime + consumerTotalTime - mainThreadTotalTime));
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
throw e;
} catch (ExecutionException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
throw e;
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ProducersConsumers prodcon = new ProducersConsumers();
prodcon.begin(20);
}
}
You should close the ExecutorService when you are done with it. Call executorPool.shutdown() at the end of your program.
You seem to be using a shared resource, specifically numOfMessages outside of a synchronized block.
while (numOfMessages > 0) {
// blah
synchronized (numOfMessages) {
// blah
}
}
I don't think this is the cause of your problem, but it's certainly non thread-safe. It's a typical check-then-act scenario. Refer to either Java Concurrency in Practice or Effective Java for reasons why this is Not Good (TM).

Setting off multi-threaded stopwatch instances (commandHolder got filled during execution of doCommandWithoutWaitingForAReponse exception)

I am trying to do something conceptually simple...
We have multiple portlets loading on a Dashboard. I need to measure the load time that each takes. I have implemented a simple StopWatch class, and need to run multiple instance of it simultaneously, for each portlet, while the Dashboard is loading.
So the parameters supplied will be:
The portlet name
The element to be checked, indicating a successful load.
Here is the StopWatch class:
public class StopWatch implements Runnable {
private long startTime;
private long stopTime;
private String tElement;
private String tPortletName;
public StopWatch(String portletName,String element) {
tElement = element;
tPortletName = portletName;
}
public void start() {
startTime = System.currentTimeMillis();
}
public void stop() {
stopTime = System.currentTimeMillis();
}
public long getTime() {
return stopTime - startTime;
}
#Override
public void run() {
selenium.selectFrame(tPortletName);
StopWatch sw = new StopWatch();
sw.start();
while (selenium.isElementPresent(tElement)==false)
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
sw.stop();
long time = sw.getTime();
System.out.println(tPortletName+" load time="+time);
}
}
In the calling program,
StopWatch sw1 = new StopWatch(portlet1,element1);
StopWatch sw2 = new StopWatch(portlet2,element2);
ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
threadExecutor.execute(sw1); // start task1
threadExecutor.execute(sw2); // start task2
Upon running this, I get the following exception:
com.thoughtworks.selenium.SeleniumException: ERROR Server Exception: commandHolder got filled during execution of doCommandWithoutWaitingForAReponse
Any clues on what causes this?
Most likely the reason is that you are sending commands faster then Selenium can process them.
Anyway this approach should not work since DefaulSelenium and other Selenium classes are not synchronized so if you most likely you will get deadlocks or unpredictable results.
I think you will have to test this in two steps: load dashboard, wait for first portlet, then reload dashboard and wait for second portlet. Do all of this in the main thread, something like:
private void waitForPortlet(String portletName, String element) {
long startTime = System.currentTimeMillis();
while (selenium.isElementPresent(element) == false)
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
long stopTime = System.currentTimeMillis();
System.out.println(portletName + " load time=" + (stopTime - startTime));
}
And use:
waitForPortlet(name1, element1);
selenium.refresh();
waitForPortlet(name2, element2);

Categories