Java Job Stuck in a while loop [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 days ago.
Improve this question
my job is stuck in a infinte loop. what seems to be the problem here? at the ned it gives me a EJB5119:Expunging timer error
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
try {
task.run();
afterExecute(task, null);
} catch (Throwable ex) {
afterExecute(task, ex);
throw ex;
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}

Related

Java NIO File-System-Watcher missing Events

For my home-automation project, i'm using some raspberries and java. To read the state of the GPIOs (Connection pins) i'm using the file-system-based api, which is quite simple:
/sys/class/gpio/gpioX/value
is a file, that simple contains 0 or 1 depending on the signals state. The system can be configured to fire interrupts whenever the value changes. Basically that means, a file system watcher monitoring this file for changes will be invoked upon change.
now, when working with a signal, where you want to detect both edges (rising and falling), it will become a bit tricky, depending on frequency. For fast signals, reading the file AFTER the FSW has been notified might already return a wrong value. (FSW notified on "1", and when reading the file, it is already "0")
So, I used a simple toggle-logic to determine the state, assuming that a notification ofc. always means a change in state. However, this sometimes falls out of sync, and when this happens, the log also shows 2 events super close together, leading to the assumption that a third one in between has been missed.
So, the general issue seems to be about how the event-gathering on the nio-fsw works, or at least how I implemented it:
this is the part of the code responsible to notify the actual value change listeners. It's already raised in a thread in order to be able to return to key.reset() asap - but still this seems to be not fast enough for high frequency signals.
At this point, I'm wondering if this is done correctly. I mean, no matter how minimal the workload between pollEvents() and key.reset() might be, in an universe full of coincidences, two events could be so close together that one of it will be missed.
If this is implemented "okay" and it is a drawback of the NIO-fsw, do other watchers, like apache-commons suffer from the same issue? (Never had any missed event with a c#-fsw)
#Override
public void run() {
try {
while (true) {
// initialize the current state, so we can reliable detect state
// changes.
if (this.lastState == null)
lastState = this.getState();
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
Path path = (Path) event.context();
//Log.d(getClass(), "Watch Event: " + event.kind() + ": " + path.toAbsolutePath());
if (path.toString().contains("value")) {
if (this.edgeMode == EdgeMode.rising) {
lastState = SimpleGPIOState.ON;
} else if (this.edgeMode == EdgeMode.falling) {
lastState = SimpleGPIOState.OFF;
} else {
if (lastState != SimpleGPIOState.ON)
lastState = SimpleGPIOState.ON;
else if (lastState != SimpleGPIOState.OFF)
lastState = SimpleGPIOState.OFF;
}
//notify each listener on a thread to be able to call
//key.reset() without waiting for processing results.
Thread notifier = new Thread(new Runnable(){
#Override
public void run() {
onStateChanged(lastState);
}
});
notifier.start();
}
}
key.reset();
if (Thread.interrupted()) {
break;
}
}
} catch (InterruptedException e) {
Log.cf(getClass(), "Listener stopped.");
} finally {
if (watchService != null) {
try {
watchService.close();
} catch (IOException e) {
// e.printStackTrace();
}
}
thread = null;
}
}
ps.: I know there is pi4j, but I don't like it :P
based on amanin comments about the count attribute of the Watch-Event, I've now modified the code (and using a ThreadpoolExecutor) - Up to now My internal state didn't fall out of sync anymore, and there are "Multi-Count-Events" logged. The appearence is very rare, but they are there. So, obviously, threading such an Event as a single Event lead to problems in synchronity.
2022-08-26 12:12:29, es.gardencontrol.gpio.concrete.FlowMeterGPIO: Throughput: 82.22 l/min (Sum: 143.13999999999993); sps: 370 , pulses: 201371
2022-08-26 12:12:30, es.gardencontrol.gpio.concrete.FlowMeterGPIO: Throughput: 83.56 l/min (Sum: 144.52999999999992); sps: 376 , pulses: 201747
2022-08-26 12:12:30, es.gardencontrol.gpio.concrete.FlowMeterGPIO: Multi-Count-Event spotted.
2022-08-26 12:12:31, es.gardencontrol.gpio.concrete.FlowMeterGPIO: Throughput: 83.33 l/min (Sum: 145.9199999999999); sps: 375 , pulses: 202122
2022-08-26 12:12:32, es.gardencontrol.gpio.concrete.FlowMeterGPIO: Throughput: 84.44 l/min (Sum: 147.3299999999999); sps: 380 , pulses: 202502
snip:
#Override
public void run() {
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
while (true) {
// initialize the current state, so we can reliable detect state
// changes.
if (this.lastState == null)
lastState = this.getState();
WatchKey key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
if (event.count() > 1){
Log.cf(getClass(), "Multi-Count-Event spotted.");
}
for (int i = 0; i < event.count(); i++){
Path path = (Path) event.context();
//Log.d(getClass(), "Watch Event: " + event.kind() + ": " + path.toAbsolutePath());
if (path.toString().contains("value")) {
if (this.edgeMode == EdgeMode.rising) {
lastState = SimpleGPIOState.ON;
} else if (this.edgeMode == EdgeMode.falling) {
lastState = SimpleGPIOState.OFF;
} else {
if (lastState != SimpleGPIOState.ON)
lastState = SimpleGPIOState.ON;
else if (lastState != SimpleGPIOState.OFF)
lastState = SimpleGPIOState.OFF;
}
//notify each listener on a thread to be able to call
//key.reset() without waiting for processing results.
executorService.submit(() -> {
onStateChanged(SimpleGPIOState.valueOf(lastState.toString()));
});
}
}
}
key.reset();
if (Thread.interrupted()) {
break;
}
}
} catch (InterruptedException e) {
Log.cf(getClass(), "Listener stopped.");
} finally {
if (executorService != null)
executorService.shutdown();
if (watchService != null) {
try {
watchService.close();
} catch (IOException e) {
// e.printStackTrace();
}
}
thread = null;
}
}
Update: replaced the listener-parameter to use a fresh copy of the lastState variable, as this might lead to concurrency issues otherwise:
onStateChanged(SimpleGPIOState.valueOf(lastState.toString()));

service.shutdownNow() not killing the thread

In my application im spawning a single thread executor and in the thread I'm doing logic of loading ML models/predictions. If any of the logic exceeds the time-limit(4 minutes), I'm shutting down the thread.
But when the application is up, when time out happens, I'm able to see logs of threads getting shut down. But the process(Prediciton logic) continues to execute.
Code snippet for creating the thread
ExecutorService service = Executors.newSingleThreadExecutor();
Future<Object> prediction = null;
try {
prediction = service.submit(() -> {
// Execute the requested Document Prediction Engine against the XML Document.
return executeEngine(tenantId, appId, engine, document, predictionParams == null ? new HashMap<>() : new HashMap<>(predictionParams)).get();
});
predictionResult = prediction != null ? (PredictionResult) prediction.get(Long.parseLong(System.getProperty(IDR_INTERNAL_TIMEOUT, "30000")),
TimeUnit.MILLISECONDS) : null;
} catch (TimeoutException e) {
if (prediction != null) {
LOGGER.debug("Task was cancelled with a {} status", (prediction.cancel(true) ? " successful" : " failure"));
}
ExpenseMetrics.internalPredictionTimeout.inc();
String message = "Prediction took more than allowed milliseconds: " + Long.parseLong(System.getProperty(IDR_INTERNAL_TIMEOUT, "30000")) +
" fileName: "+ documentFile.getFileName();
if (service != null && !service.isShutdown()) {
service.shutdownNow();
}
service = null;
throw new IDRExmClientException(message, requestId, ErrorCode.INTERNAL_TIMEOUT);
}
if (service != null && !service.isShutdown()) {
service.shutdownNow();
}
service = null;
Code snippet for Prediction logic and timeout
List<Callable<Void>> taskList = new ArrayList<Callable<Void>>();
taskList.add(callable1);
taskList.add(callable2);
ExecutorService executor = null;
List<Future<Void>> futures = null;
long s = System.currentTimeMillis();
try {
executor = Executors.newFixedThreadPool(THREAD_POOL);
futures = executor.invokeAll(taskList);
executor.shutdown();
if (!executor.awaitTermination(TOLERANCE_MINUTES, TimeUnit.MINUTES)) {
LOGGER.warn("Document predict thread took more than {} minutes to shutdown", TOLERANCE_MINUTES);
executor.shutdownNow();
}
} catch (InterruptedException iex) {
LOGGER.error("Document predict thread was interrupted", iex);
} finally {
cancelFutures("Predict", futures);
LOGGER.debug("Document predict thread took: {}", (System.currentTimeMillis() - s));
if (executor != null && !executor.isShutdown()) {
executor.shutdownNow();
}
}
executor = null;
from the Oracle documentation of the method shutDownNow() :
There are no guarantees beyond best-effort attempts to stopprocessing actively executing tasks. For example, typicalimplementations will cancel via Thread.interrupt, so any task that fails to respond to interrupts may never terminate.
you can see this answer it may help you:
ExecutorService is not shutting down

SonarLint saying socket is not closed even closed

I have the following piece of code. SonarLint saying socket should be closed in finally block.
But I have already closed it.
I have observed one more thing here is: I am getting this only if I have serverSocket.isClosed() condition in finally if condition. If I remove it, the issue is solved.
Here I wanna know that what is the problem with this condition becoz of that sonarLint could not recognize the socket closing.
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(5555);
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(serverSocket != null && !serverSocket.isClosed())
{
try
{
serverSocket.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Because of the this : if(serverSocket != null &&
You are using an if statement and checking if the serverSocket in NOT NULL AND
here the problem is that is serverSocket is not null then the && operator will not let the next condition to execute and the if statement will not execute,eventually, the connection will not closed.

How to move Cursor in Java Jsoup while loop? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm using Jsoup with while loop but the cursor stuck at a=0. I have tried to move it by added doc.next(); but not working. I want a run from 0-29 in the url. Thank you!
Edited: The url structure is www.example.com/0, www.example.com/1,www.examplecom/2,www.example.com/3,www.example.com/4.....to unlimited "a", but only one number contain the information i need ( range from 0-30). There is no 404 return. The problem is the cursor does not move to the next "a", it's stuck at a=0. There must be someway to make the cursor move because the loop don't move it.
try {
int a = 0;
boolean condition = true;
while (a < 30 && condition) {
doc = Jsoup.connect("http://www.example.com/" + a).get();
Elements info = doc.select("td[valign=top]");
if (null != info) {
System.out.println(info);
condition = false;
System.out.println(a);
} else {
a = a + 1;
}
}
} catch (Exception e) {
}
I'm not sure what exactly you are trying to achieve here, but I will tell you why the loop is stuck at 0.
It is because the url you are trying to access with Jsoup (e.g. www.google.com0) is not a valid url, and it will return a 404 response, which Jsoup will treat as a http exception, and hence the loop is stopped and the control goes to catch block to catch the exception.
If you really want to go from 0 to 29, below code will work for you:
UPDATE:
I now see the problem. Change your code to this:
try {
int a = 0;
boolean condition = true;
while (a < 30 && condition) {
try{
doc = Jsoup.connect("http://www.google.com" + a).get();
} catch(Exception jsoupE){
continue;
}
Elements info = doc.select("td[valign=top]");
if (info.first() != null) {
System.out.println(info);
condition = false;
System.out.println(a);
} else {
a = a + 1;
}
}
} catch (Exception e) {
}

error: exception IOException is never thrown in body of corresponding try statement [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I receive an error each time. What am I doing wrong?
My Code:
public static void hashMap(String crnString)
{
try
{
if (mMap.containsKey(crnString))
{
int count = mMap.get(crnString);
count++;
mMap.put(crnString, count);
}
else
{
mMap.put(crnString, 1);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
}
}
Assuming mMap is a HashMap, the code inside the try block never throws an IOException. Remove the try-catch block wrapping your code.
public static void hashMap(String crnString){
if (mMap.containsKey(crnString)) {
int count = mMap.get(crnString);
count++;
mMap.put(crnString, count);
} else {
mMap.put(crnString, 1);
}
}
IOException is checked exception. So code in try block is not potential code that can raise IOExcption that's why the compiler shows error. Use specific exception type catch block that can be raised or use unchecked exception catch block. In you try block code, only NPE can be raised.
try
{
if (mMap.containsKey(crnString))
{
int count = mMap.get(crnString);
count++;
mMap.put(crnString, count);
}
else
{
mMap.put(crnString, 1);
}
} catch (NullPointerException e)
{
e.printStackTrace();
} catch(Exception e) {
System.out.println("Unexcepted Exception");
e.printStackTrace();
}
finally
{
}

Categories

Resources