Java Thread StackOverflowError - java

...
Thread showWordThread = new Thread() {
public void run() {
try {
sleep(config.delayTime * 1000);
} catch (Exception e) {
System.out.println(e.toString());
}
this.run();
}
};
showWordThread.run();
}
...
It had run for about 5 minutes before error occured:
Exception in thread "Thread-2" java.lang.StackOverflowError.
Why?
I had tried this:
Thread showWordThread = new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(config.delayTime * 1000);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
});
showWordThread.start();
But error still occured.

Others have explained that you should use a while loop instead. You're also trying to call the run method inside your anonymous class declaration. Additionally, you should call start, rather than run - when the new thread has started, it will call run automatically. I'd actually suggest implementing Runnable rather than extending Thread, too. So you want:
Thread showWordThread = new Thread(new Runnable() {
#Override public void run() {
while (someCondition) {
try {
Thread.sleep(config.delayTime * 1000);
// Presumably do something useful here...
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
});
showWordThread.start();
Alternatively, consider using a Timer or ScheduledExecutorService.

You are calling run method as recursively. Java holds call information(such as parameters) in stack memory so when you are calling a method recursively and there isn't any end point, stack memory will consumed and StackOverflow exception throws.
Maybe you want increasing Heap Size of JVM but this solution don't solve your problem and StackOverflow will occurred .
I guess you want run a thread continually. I recommend following code:
Thread showWordThread = new Thread()
{
public void run()
{
try
{
sleep(config.delayTime * 1000);
}
catch (Exception e)
{
System.out.println(e.toString());
}
// this.run(); this snnipet code make error
}
};
showWordThread.run();
}

Don't call run() from within the run() method. That'll definitely produce a stack overflow because you keep reentering the same method with no exit condition. Instead use a while loop.
Thread showWordThread = new Thread() {
public void run() {
while(condition) {
try {
sleep(config.delayTime * 1000);
} catch (Exception e) {
System.out.println(e.toString());
}
}
};
showWordThread.start();
}

Your code have infinity recursive, you should change the code to:
Thread showWordThread = new Thread() {
public void run() {
while (true) {
try {
Thread.sleep(config.delayTime * 1000);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
};
showWordThread.start();

Your function calls itself each time you run it.
That results in a stack overflow.

Maybe because you call run method (this.run()) from itself?

Related

Why there is only one thread can actually started in #PostConstruct method?

#Component
class Type
{
#PostConstruct
private void postConstructor() {
Runnable threadAlpha = () -> {
while (true) {
workWithSomething();
try {
Thread.sleep(1000 * 60);
} catch (InterruptedException e) {
}
}
};
Runnable threadBeta = () -> {
while (true) {
workWithOtherthing();
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
}
}
};
threadBeta.run();
threadAlpha.run();
}
}
With spring-framework, I am struggling with this piece of code, the problem is only one thread can actually started which call run() first, the other one seems freezing, If I switch the location to be like:
threadAlpha.run();
threadBeta.run();
Then threadBeta never started, why something happen like that?
Because you're not creating threads. Instead of that you're creating Runnable instances and then running their run method.
Instead do this:
new Thread(threadAlpha).start();
new Thread(threadBeta).start();
The Runnable run() executes in the current thread and hence the behavior. If you want to run in two separate threads use Thread and call start on those:
public class SpringMultipleThreads {
public static void main(String[] args) {
new SpringMultipleThreads().postConstructor();
}
private void postConstructor() {
Thread threadAlpha = new Thread(() -> {
while (true) {
System.out.println("1");
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
}
}
});
Thread threadBeta = new Thread(() -> {
while (true) {
System.out.println("2");
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
}
}
});
threadBeta.start();
threadAlpha.start();
}
}
When you call threadAlpha.run() and threadBeta.run() you are executing it in the current thread. For simple execution in new thread you can use:
Thread t1 = new Thread(threadAlpha);
t1.start();
Thread t2 = new Thread(threadBeta);
t2.start();
SimpleThreads tutorial from Oracle.
When you are calling threadBeta.run() or threadAlpha.run() you are calling a method which has an infinite loop. You are not creating a thread. That's why threadAlpha.run() isn't executing even as threadBeta.run() is in an infinite loop. Instead you can do this:
new Thread(threadBeta).start();
new Thread(threadAlpha).start();

Threads producer consumer in java

Below is the consumer producer problem code, but the code is not working as expected. Here the consumer and producer are supposed to be just producing and consuming one object.
public class ProducerConsumer {
private static LinkedList<Integer> linkedList = new LinkedList<>();
public static void main(String a[]) throws InterruptedException {
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized(this) {
while (linkedList.size() == 1) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized(this) {
while (linkedList.isEmpty()) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
We get the output as : Produced
And the program hangs.
Please help with possible solutions/ explanations
Use a shared lock. In the posted code each Runnable is using itself as a lock so no actual locking takes place.
When a thread waits, another thread needs to call notify on the same lock in order to wake up the waiting thread. We know from your logging that the Producer thread does its thing, but since the notify acts on a lock that is not the same as the one the Consumer is using, the consumer thread never wakes up.
Changing the code to use a shared lock works:
import java.util.*;
public class ProducerConsumer { private static LinkedList linkedList = new LinkedList();
public static void main(String a[]) throws InterruptedException {
final Object lock = new Object();
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
while (linkedList.size() ==1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized (lock) {
while (linkedList.isEmpty()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
Output for this is:
c:\example>java ProducerConsumer
Produced
Consumed
which I think is what you're expecting.
Btw see this other answer I wrote for a dirt-simple implementation of a queue; you are better off protecting the shared data structure than putting the code in the threads accessing the data structure, especially look at how much easier the code is to write.
Concurrency means that you can not know before runtime which Thread will end first. So you can not know which of the Consumer and Producer is launched, executed or finished first.
To help you, you can use a cyclic barrier https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html or applying the Fork/Join Framework https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
Your synchronized blocs just say : only one Thread at a time can execute this part of code, not execute the first and the second after.
An example of how CyclicBarrier works :
service = Executors.newFixedThreadPool(numThreadsTotal);
CyclicBarrier c = new CyclicBarrier(numThreadsToWait);
runProducer();
c.await();
runConsumer();
It will wait until the there is as much Threads as numThreadsToWait that have execute the runProducer to execute the runConsumer().
Perhaps using a Thread Pool with a size of 1 could help you, but you will loose the benefits of concurrency.
I think best what you can do, is use BlockingQueue.

thread pool server shut down gracefully

I have a simple http server implemented with thread pool. I want to shut down the server gracefully. I referred the post Best Way to Gracefully Shutdown a Java Command Line Program
Here is the basic code:
public static void main(String[] args) {
ThreadPoolServer threadserver = new ThreadPoolServer(9000);
new Thread(threadserver).start();
threadserver.attachShutDownHook();
while (true) {
try {
Thread.sleep(20 * 10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void stopthread(){
this.shutdown = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
public synchronized void attachShutDownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
stopthread();
}
});
}
But it seems it does not stop the right way, any ideas? Thx.
This is too small piece of code.
But at the first sight I don't see any check for shutdown value in the main while loop. Secondly the variable should be set after and probably join on the listening thread would be worthy. In the run method I assume you properly handle the exception raised by asynchronous close.

Time out method in java

In a java class I have a method that sometimes takes a long time for execution. Maybe it hangs in that method flow. What I want is if the method doesn't complete in specific time, the program should exit from that method and continue with the rest of flow.
Please let me know is there any way to handle this situation.
You must use threads in order to achieve this. Threads are not harmful :) Example below run a piece of code for 10 seconds and then ends it.
public class Test {
public static void main(String args[])
throws InterruptedException {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("0");
method();
}
});
thread.start();
long endTimeMillis = System.currentTimeMillis() + 10000;
while (thread.isAlive()) {
if (System.currentTimeMillis() > endTimeMillis) {
System.out.println("1");
break;
}
try {
System.out.println("2");
Thread.sleep(500);
}
catch (InterruptedException t) {}
}
}
static void method() {
long endTimeMillis = System.currentTimeMillis() + 10000;
while (true) {
// method logic
System.out.println("3");
if (System.currentTimeMillis() > endTimeMillis) {
// do some clean-up
System.out.println("4");
return;
}
}
}
}
Execute the method in a different thread, you can end a thread at anytime.
Based on the above snipplet, I tried creating a glorified spring bean.
Such executor runs the passed limitedRuntimeTask in limited runtimeInMs.
If the task finishes within its time limits, the caller continues normally in execution.
If the limitedRuntimeTask fails to finish in the defined runtimeInMs,
the caller will receive the thread execution back. If a timeBreachedTask was defined,
it will be executed before returning to caller.
public class LimitedRuntimeExecutorImpl {
public void runTaskInLessThanGivenMs(int runtimeInMs, final Callable limitedRuntimeTask, final Callable timeBreachedTask) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
LOGGER.info("Started limitedRuntimeTask");
limitedRuntimeTask.call();
LOGGER.info("Finished limitedRuntimeTask in time");
} catch (Exception e) {
LOGGER.error("LimitedRuntimeTask exception", e);
}
}
});
thread.start();
long endTimeMillis = System.currentTimeMillis() + runtimeInMs;
while (thread.isAlive()) {
if (System.currentTimeMillis() > endTimeMillis) {
LOGGER.warn("LmitedRuntimeTask did not finish in time (" + runtimeInMs + ")ms. It will run in vain.");
if(timeBreachedTask != null ){
try {
LOGGER.info("Executing timeBreachedTask");
timeBreachedTask.call();
LOGGER.info("Finished timeBreachedTask");
} catch (Exception e) {
LOGGER.error("timeBreachedTask exception", e);
}
}
return;
}
try {
Thread.sleep(10);
}
catch (InterruptedException t) {}
}
}
}
I feel the approach in accepted answer is a bit outdated. With Java8, it can be done much simpler.
Say, you have a method
MyResult conjureResult(String param) throws MyException { ... }
then you can do this (keep reading, this is just to show the approach):
private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor();
MyResult conjureResultWithTimeout(String param, int timeoutMs) throws Exception {
Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param));
return future.get(timeoutMs, TimeUnit.MILLISECONDS);
}
of course, throwing Exception is bad, here is the correct extended version with proper error processing, but I suggest you examine it carefully, your may want to do some things differently (logging, returning timeout in extended result etc.):
private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor();
MyResult conjureResultWithTimeout(String param, int timeoutMs) throws MyException {
Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param));
try {
return future.get(timeoutMs, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
//something interrupted, probably your service is shutting down
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (ExecutionException e) {
//error happened while executing conjureResult() - handle it
if (e.getCause() instanceof MyException) {
throw (MyException)e.getCause();
} else {
throw new RuntimeException(e);
}
} catch (TimeoutException e) {
//timeout expired, you may want to do something else here
throw new RuntimeException(e);
}
}

In Java: how can I make thread watch over another thread?

Sorry if the question is quite simple. I am a beginner.
I have to create thread that calulates something, while the first thread works the other one have to measure if the first thread calculate the function in specified time. If not, it has to throw exception. Else it returns the answer.
I'd take the java.util.concurrent components - simple example
public void myMethod() {
// select some executor strategy
ExecutorService executor = Executors.newFixedThreadPool(1);
Future f = executor.submit(new Runnable() {
#Override
public void run() {
heresTheMethodToBeExecuted();
}
});
try {
f.get(1000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// do something clever
} catch (ExecutionException e) {
// do something clever
} catch (TimeoutException e) {
// do something clever
}
}
Have your thread notify a synchronization object when it is done and have your other thread wait x number of milliseconds for it to finish.
public class Main {
private static final Object mThreadLock = new Object();
static class DoTaskThread extends Thread {
public void run() {
try {
int wait = new Random().nextInt(10000);
System.out.println("Waiting " + wait + " ms");
Thread.sleep(wait);
} catch (InterruptedException ex) {
}
synchronized (mThreadLock) {
mThreadLock.notifyAll();
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
synchronized (mThreadLock) {
DoTaskThread thread = new DoTaskThread();
thread.start();
try {
// Only wait 2 seconds for the thread to finish
mThreadLock.wait(2000);
} catch (InterruptedException ex) {
}
if (thread.isAlive()) {
throw new RuntimeException("thread took too long");
} else {
System.out.println("Thread finished in time");
}
}
}
}
join is a lot simpler than using a lock.
join (millis)
Waits at most millis milliseconds
for this thread to die. A timeout of 0
means to wait forever.
Example code:
Thread calcThread = new Thread(new Runnable(){
#Override
public void run() {
//some calculation
}
});
calcThread.start();
//wait at most 2secs for the calcThread to finish.
calcThread.join(2000);
//throw an exception if the calcThread hasn't completed.
if(calcThread.isAlive()){
throw new SomeException("calcThread is still running!");
}
Have a look at http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination(long,%20java.util.concurrent.TimeUnit) which allows you to handle this without dealing with thread synchronization yourself.

Categories

Resources