Java endless recursion and StackOverflowError - java

Sorry, for probably a dumb question, I'm new to Java.
Is there a way to make an endless recursion in Java, somithing like:
public void sillyMethod()
{
System.out.println(i);
i++;
sillyMethod();
}
it throws StackOverflowError, but I really want to run it endless. Is there any way to make it?
Thanks!

Yes and no, (but mostly no! :)
No, it's not possible (the most sensible answer): For every call, there will be an activation record pushed onto the JVM call stack. This takes a non-zero amount of memory, thus you will at some point run out of memory, at which point a StackOverflowException will be thrown.
Yes, it is possible (the super-theoretical answer): There is nothing in the Java Language Specification that explicitly says that you should eventually run into a StackOverflowException. This means that if you find a cleaver enough compiler, it may be intelligent enough to compile this into a loop.
A related question would be, "Does the JVM support tail-call optimization." The answer to this question is, "no, not at moment, but it's not ruled out for future versions".

As others above have said, infinite recursion will eventually lead to a stack overflow, at least as far as the JVM implementation is concerned.
You could do something like this, which is similar, but avoids the stack expansion by spawning a new thread right before the old one dies.
public class SillyClass implements Runnable {
private final int count;
public SillyClass(int cnt) {
this.count = cnt;
}
public static void main(String[] args) {
Thread t = new Thread(new SillyClass(0));
t.start();
}
#Override
public void run() {
System.out.println(count);
Thread t = new Thread(new SillyClass(count + 1));
t.start();
}
}

Not recursively, no. It does imply creating an ever-increasing call stack, and eventually you will run out of memory to contain it.

With Java, you cannot do this. However, tail call optimization in languages (esp. functional ones such as Ocaml), you can do this since it internally turns it into a loop.

Related

Wait for method to Finish, and weird interaction with System.println

I am trying to write a genetic program to play through a game, but I am running into a bit of a snag. When I call this code:
public double playMap (GameBoard gb, Player p) {
gb.playerController = p;
Game g = new Game(gb);
int initHP = 0;
for (Unit u : gb.enemy.units) {
initHP += u.maxHP;
}
g.playGame(false);
int finalHP = 0;
for (Unit u : gb.enemy.units) {
finalHP += u.currHP;
}
System.out.println(" " + initHP);
System.out.println(" " + finalHP);
System.out.println(" " + (finalHP - initHP));
if (initHP == finalHP) {
return -10;
}
return initHP - finalHP;
}
the g.playGame() line does not have time to finish, and I am getting incorrect results from the function. I can wait out unit the game is over with a
while (!g.isDone) {
System.out.println(g.isDone);
}
but not with the same while loop without a print statement. I know there has to be a more elegant solution, and I cant seem to implement the methods I have seen. Also if anyone knows why I need the print statement in the while loop to get it to wait that would be great too.
Thanks in advance.
ADDED playGame:
public void playGame(boolean visual) {
Global.visual = visual;
if (Global.visual) {
JFrame application = new JFrame();
application.setBackground(Color.DARK_GRAY);
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.add(this);
application.setSize(500, 400); // window is 500 pixels wide, 400 high
application.setVisible(true);
}
PlayerInput pi = new PlayerInput();
this.addKeyListener(pi);
final Timer timer = new Timer(10/60, null);
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pi.addPressed();
if (update(pi)) {
// application.setVisible(false);
// application.dispose();
System.out.println(gb.toString());
isDone = true;
timer.stop();
}
pi.reset();
}
};
timer.addActionListener(listener);
timer.start();
while (!isDone) {
System.out.println(isDone);
}
}
First of all, this is a really bad way of doing this. This approach is called "busy waiting" and it is very inefficient.
The problem is most likely that reads and writes to g.isDone are not properly synchronized. As a consequence, there are no guarantees that the "waiting" thread will ever see the update to g.isDone that sets it to true.
There are various ways to ensure that the update is seen. The simplest one is to declare isDone as volatile. Another one is to do the reads and writes within a primitive lock.
The reason that the println() call "fixes" things is that println is doing some synchronization behind the scenes, and this is leading to serendipitous cache flushing (or something) that makes your update visible. (In other words: you got lucky, but exactly how you got lucky is hard to tie down.)
A better solution is to use another mechanism for coordinating the two threads.
You could use Thread.join() so that one thread waits for the other one to terminate (completely!).
You could use a Latch or Semaphore or similar to implement the waiting.
You could use an Executor that delivers a Future and then call Future.get() to wait for that to deliver its result.
You could even use Object.wait and Object.notify ... though that is low-level and easy to get wrong.
Without seeing the full context, it is hard to judge which approach would be most appropriate. But they would all be better than busy-waiting.
Another answer says this:
If you remove the System.out.println() call from your loop, I believe that the compiler simply doesn't include the loop in the Java bytecode, believing it to be superfluous.
As I explained above, the real problem is inadequate synchronization. To be technical, there needs to be a happens-before relationship between the write of isDone in one thread and the read of isDone in the other one. Various things will give that ... but without that, the compiler is entitled to assume that:
the writing thread does not need to flush the write to memory
the reading thread does not need to check that the memory has changed.
For example, without the happens-before, the compiler would be permitted to optimize
while (!g.isDone) {
// do nothing
}
to
if (!g.isDone) {
// do nothing
}
We don't know if this actually happens, or whether the actual cause of "non-visibility" of the update to isDone is something else. (Indeed, it could be JVM version / platform specific. To be sure, you would need to get the JIT compiler to dump the native code for the methods, and analyze the code very carefully.)
Apparently you are running your game in a separate thread. Assuming that thread is called foo, calling foo.join() will block the calling thread until foo finishes executing. You can simply replace your entire loop with foo.join().
If you remove the System.out.println() call from your loop, I believe that the compiler simply doesn't include the loop in the Java bytecode, believing it to be superfluous.

How to trigger the reordering phenomenon in Java?

In a book called "Java Concurrency in Practice", I saw a sample code like this at the beginning of chapter 3
public class NoVisibility {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready)
Thread.yield();
System.out.println(number);
}
}
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
}
The book says
"NoVisibility could loop forever because the value of ready might never become visible to the readerthread."
and
"NoVisibility could print zero because the write to ready might be made visible to the readerthread before the write to number, a phenomenon known as reordering."
I'd like to know how to trigger any one of the above events(i.e., loop forever or print zero).
Does anyone know how to make this happen?
I've tried executing this program on my machine(javaSE-1.7 on windows 8.1) for many times. It always print 42 as the result.
There's a lot of mysteries about multithreading, and you'll hurt your head trying to reason why things go wrong. Its easier to just do things right. That being said my elementary understanding is optimizations are made by the machine behind the scene that prevents threads from seeing the latest value posted by another thread. If you need an example just post some sleeping threads and have one change the value and another one read it later. Of the failure occurs there will be two different values for the supposed single value.

Java/Swing - passing Application object

I'm having some performance problems on a Swing based application I've been tasked with maintaining - I suspect a memory leak. After profiling, it appears that there is a very large amount of time being spent in the main application class (ie the entry point), specifically in a method that passes a reference to it's own Application object, like this:
public synchronized static ProblemApplication getApplication() {
if (s_Instance == null) {
initializeInstance();
}
return (ProblemApplication ) s_Instance;
}
private synchronized static void initializeInstance() {
s_Instance = Application.getInstance();
}
This is called a lot throughout the code - a typical usage:
private void updateSensorsModel() {
ProblemApplication application = ProblemApplication .getApplication();
int sensorIndex = 0;
m_SensorModels.clear();
// add sensors information
for (SensorConfiguration s : application.getSensorsConfiguration().getSensors()) {
m_SensorModels.add(new SensorModel(sensorIndex, application));
sensorIndex++;
}
// add extra session information
for (ExtraSession es : application.getSession().getExtraSessions()) {
m_SensorModels.add(new SensorModel(-1, application, es.getDeviceID()));
}
}
and with some action listeners:
// listeners
final TechsasSession session = TechsasApplication.getApplication().getSession();
session.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("sensorsConfiguration")) {
SensorTableModel model = sensorTable.getModel();
model.updateModel();
repaint();
}
}
});
Anyway I've got very little Swing, and my Java (especially this kind of stuff) is a bit rusty.
Is this use of a synchronised singleton application object legitimate in this kind of environment?
I know that particular usages of it could be causing issues even if the approach is sound, I guess I just want to know if this is a likely candidate for my problems and something I should investigate further. The usage feels wrong to me - but that could just be me!
Thanks for your help.
I think you might solve this by eliminating the synchronized nature of the method; to do that, just initialize the variable when the class is loaded. The obvious way to do this is with a static initializer, which you may need to look up -- it is a code block that is executed when the class is loaded, so it completes before any use of the class is made.
Synchronizing a method can take significant time in comparison to method calls without synchronization, so this is an easy thing to try. It doesn't have much to do with Swing, but it's a lot simpler to do something about in this case.
edit: --------------------
You don't say why you suspect a memory leak, or indeed what you mean by a "performance problem"; I think it is far more usual, in a Swing or other GUI application, to have a "performance problem" somewhere besides the synchronized call to a method, even if it's called often. But this is the code you identified, and the first thing I saw about it related to performance. I hope it helps, but it won't surprise me much if your problem is something you have not said and is caused by something you haven't mentioned. Just saying.

Variable depth recursion in Java

So I'm doing a little experiment on exactly how far recursion can go in the Java language since I'm taking a class on concurrency and learning about Java's threading mechanisms. Right now I'm running a Intel i5 Quad-core with 2.8 GHz and 4GB of RAM. I'm running on Windows 7 with x64 and in Eclipse with the standard JRE? Not sure about that last part I just downloaded something from Sun's website.
Anyway,
public class StacksizeTest implements Runnable {
int depth = 0;
public void run()
{
try
{
doOverflow();
}
catch (StackOverflowError e)
{
System.out.print("Overflow ocurred at depth " + depth + ".\n");
}
}
void doOverflow()
{
depth += 1;
doOverflow();
}
public static void main(String argv[])
{
Thread mt = new Thread(new StacksizeTest());
mt.start();
mt.run();
}
}
I'm also running with the default call stack size, which im pretty sure is 512Mb according to the settings file.
So when I run the program and start a new thread I keep getting variable depths, as well as the print statement printing twice. The print statement makes sense I think because it should be running mt on a new thread. What I'm confused about is if I exclude .start() and just call .run() the "depth" is always the same (about 11,500 or so), but when I use .start() I'm getting variable depths. a couple have been 22789, 22330, and 22381. I'm having difficulty understanding why this is. Could someone possibly shed some light on this issue?
Thanks,
Matt
The call to .start() will start a new thread with run(), then you're calling run() again on the main thread. So you've got two stack depth threads running at the same time. Since you've also got a shared variable counting the depth that's not protected by a synchronized mutex, you've got a classic variable contention problem.
In order not to confuse the issue with variable contention, I would limit yourself to one running instance of the stack depth checker.
When you call start() you're firing off the method asynchronously, so you're running it twice because start() eventually makes a call to run(), and in addition you're calling run() yourself, so you've got two threads incrementing your depth counter. Eliminate the start(), and you get your smaller count because you're only running a single thread.
EDIT: I just saw Greg's answer. I like his more.

Does this require synchronization?

In the class below, I am using a singleThreadScheduledExecutor. My question is, do I need to synchronize around the access to dummyInt and dummyBoolean?
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Playground {
/**
* #param args
*/
public static void main(String[] args) {
startThread();
}
private static void startThread() {
ScheduledExecutorService timer = Executors
.newSingleThreadScheduledExecutor();
Runnable r = new Runnable() {
int dummyInt = 0;
boolean dummyBoolean = false;
#Override
public void run() {
dummyInt = dummyInt + 1;
if (dummyBoolean) {
dummyBoolean= false;
} else {
dummyBoolean= true;
}
}
};
timer.scheduleAtFixedRate(r, 0, 100, TimeUnit.MILLISECONDS);
}
}
No, you don't. There is only a single thread accessing the values, so no synchronization is required.
Every thread you start with that mechanism will have its own instance of the "Runnable" subclass you define and instantiate. Therefore, there can't possibly be contention.
Do you need to? No. Only a single thread will ever access the variables in the current implementation, so it is thread safe.
Would it hurt performance to? Well, yes, but not by as much as you would probably expect. The modern JIT compilers are quite happy to spot that the synchronization is unnecessary in the current usage, and eliminate virtually all the overhead from the compiled code - but there would be a little overhead remaining that checked whether the assumption of single-threaded access was still valid. And of course, there is the overhead of JITting this.
Would it ever hurt not to synchronize? Well, possibly, if the implementation ever changed and the assumption of single thread access no longer held - and the developer making the change overlooked that consequence of their change.
But actually, in this context, is that likely to occur? Maybe not - all the code is contained in a very small area...
I'd probably leave some kind of comment documenting the assumption. I might even annotate the class as #NotThreadSafe, if I was using the JCIP annotations anywhere else in my project. A discussion of the use of those annotations can be found in the Java Concurrency In Practice book by Brian Goetz, and the annotation source code and a jar file are available for download from the book's web site.
You dont have to make it synchronized
No, but it probably wouldn't hurt. Since you're using a newSingleThreadScheduledExecutor which promises that
Tasks are guaranteed to execute
sequentially, and no more than one
task will be active at any given time.
but if you ever change executors, let the Runnable get out so other can invoke it, or check the value externally, then you'll wish you'd synchronized it.
dummyInt = dummyInt + 1;
This statement is actually 3 separate operations:
Read the value of dummyInt
Add 1
Write the value back to dummyInt
So yes you do need to synchronize this. It is possible for one thread to read the value, then another thread does all three operations, and when the first thread finishes the value is only increased by 1 (I hope this makes sense :P).dummyBoolean is similar. You read it in the if statement and the write the new value.
EDIT
Sorry for not reading the question correctly.
According to the javadoc this shouldn't need sync.

Categories