Though I know it'll be a bit silly to ask, still I want to inquire more about the technical perspective of it.
A simple example of an infinite loop:
public class LoopInfinite {
public static void main(String[] args) {
for (;;) {
System.out.println("Stack Overflow");
}
}
}
How can I interrupt (stop) this infinite loop from outside of this class (e.g., with the help of inheritance)?
I feel dirty even writing this, but...
From a different thread, you could call System.setOut() with a PrintStream implementation, which throws a RuntimeException when you call println().
We can achieve it using volatile variable, which we will change ouside Thread and stop the loop.
for(;!cancelled;) /*or while(!cancelled)*/{
System.out.println("Stackoverflow");
}
This is better way to write Infinite Loop.
public class LoopInfinite{
private static volatile boolean cancelled=false;
public static void main(String[] args){
for(;!cancelled;) { //or while(!cancelled)
System.out.println("Stackoverflow");
}
}
public void cancel(){
cancelled=true;
}
}
You can get at the thread running the infinite loop from a different thread and call interrupt on it. You'll have to be very sure what you are doing though, and hope that the interrupted thread will behave properly when interrupted.
Here, I've named the thread with the offending loop for easier identification. Beware that the following solution is vulnerable to race conditions.
Thread loop = new Thread() {
public void run() {
Thread.currentThread().setName("loop");
while(true) {
System.out.print(".");
}
}
}.start();
Then in some other class:
ThreadGroup group = Thread.currentThread().getThreadGroup();
Thread[] threads = new Thread[group.activeCount()];
group.enumerate(threads);
for(Thread t : threads) {
if(t.getName().equals("loop")) {
/* Thread.stop() is a horrible thing to use.
Use Thread.interrupt() instead if you have
any control over the running thread */
t.stop();
}
}
Note that in my example I assume the two threads are in the same ThreadGroup. There is no guarantee that this will be the case, so you might need to traverse more groups.
If you have some control over this, a decent pattern here would be to have while(!isInterrupted()) instead in the loop declaration and use t.interrupt() instead of t.stop().
My only advice to you, even after posting this, is to not do this. You can do it, but you really shouldn't.
I think this is not possible. Only using break within the loop. You could use
while(cond) {}
And from some other place make it false
You can interrupt this thread by keeping its static reference of inherited reference to this Thread [main] by asking from Thread.currentThread(), like this
public class LoopInfinite{
public static Thread main = null;
public static void main(String[] args){
main = Thread.currentThread();
for(;;)
System.out.println("Stackoverflow");
}
}
And to terminate you can call this from some other thread
LoopInfinite.main.interrupt();
But it will only work if both threads are part of the same group. Otherwise calling thread will get SecurityException
You cannot stop this from outside of this class. If you use inheritance you can overwrite your loop, but without abort-flag you won't be able to do so.
Very open question, but stopping such loop would most likely require you to operate from another thread. The other thread would then need to set some variable that your infinite loop can check regularly, and if the variable has a certain value; break out of the loop.
You won't be able to interrupt this particular loop without halting the process entirely. In general, if you're trying to do it from an external source (I'm assuming you have no control over the source code, because if you did you could easily set a condition in the loop, such as a boolean you could set from an external Thread), you will have to halt the running Thread, whether you do this through the Thread object (you'll have to find a reference to it somehow, for example by looping through existing Threads), or whether you halt it as a system process.
Another option would be to override the method with a loop that isn't an infinite loop, but unfortunately that doesn't apply to your example because it's a static method.
Your kind of problem looks like a Threading problem. But still, it is now a a good practice to include a stopping flag even in threads
If you need an "infinite" loop, you sure need a thread (else your app will be stuck until the end of the loop).
class BigLoop extends Thread
{
private boolean _sexyAndAlive = true;
// make some constructor !
public void softTerminate()
{
_sexyAndAlive = false;
}
public void run()
{
try
{
while( _sexyAndAlive )
{
// Put your code here
}
}
catch( Some Exceptions ... )
{
// ...
}
// put some ending code here if needed
}
}
// in another file :
BigLoop worker = new BigLoop();
worker.start(); // starts the thread
// when you want to stop it softly
worker.softTerminate();
So, this is a simple method to have background running loop.
Add a variable shouldBreak or something which can be set using getter and setter.
public class LoopInfinite {
private boolean shouldBreak = false;
public boolean isShouldBreak() {
return shouldBreak;
}
public void setShouldBreak(boolean shouldBreak) {
this.shouldBreak = shouldBreak;
}
public static void main(String[] args) {
// Below code is just to simulate how it can be done from out side of
// the class
LoopInfinite infinite = new LoopInfinite();
infinite.setShouldBreak(true);
for (;;) {
System.out.println("Stackoverflow");
if (infinite.shouldBreak)
break;
}
}
}
Here is what I did:
while(Exit == false){
Scanner input = new Scanner(System.in);
String in = input.next();
switch(in){
case "FindH":
FindHyp hyp = new FindHyp();
float output = hyp.findhyp();
System.out.println(output);
case "Exit":
Exit = true;
break;
}
}
Related
To my understanding the following code should terminate normally as the condition stopRunning = true; is met.
However, when I run this program it is printing only Last line of Main(), Start Method ended is never printed as the while loop is never terminated.
public class Test {
private static boolean stopRunning = false;
public static void main(String[] args) throws Exception {
new Thread(new Runnable() {
#Override
public void run() {
start();
}
}).start();
Thread.sleep(100);
stopRunning = true;
System.out.println("Last line of Main()");
}
public static void start() {
while (!stopRunning) {
}
System.out.println("Start Method ended.");
}
}
Please help me understand this behavior.
Changing the flag to volatile with
private static volatile boolean stopRunning = false;
will mean that other threads see the change immediately (from main memory instead of a cache), and the code executes as you expect. How volatile relates to Java's memory model is explained further e.g. in this tutorial.
As Mick stated, you should use the volatile keyword to synchronize your variable, so on a change the new value is written directly back to memory and your code will work as expected.
Be aware (also stated in the article Mick linked) that volatile does not guarantee to avoid race conditions, so if two different threads would read your variable, it is not safe that they both read the same value (despite everything is read from memory and on change directly written back)
As stated in previous answers:
Like Mike stated - in run() you should use Test.start() or rename the method. The start you are calling is the thread's start method.
Also as Mick stated, setting stopRunning as volatile should help. The reason it should work is that it will remove the caching of the variable in the thread's memory and will get/set directly from memory.
In the below code I have implemented inter Thread communication using wait() -notify() and it is giving me expected output.
expected Output : 123456789 Actual output : 123456789
My question is , is there any guarantee that always 'Main Thread' will get the first chance to execute, since Thread scheduling depends on jvm. And if 'child thread' gets the first chance, the notify() signal will miss and the 'main Thread ' will wait forever. How can I confirm that 'Main thread' will execute first always. Also please confirm if the below code can be improved.
package com.test.Thread;
public class ThreadExample1 {
public static void main(String[] args) throws InterruptedException{
ThreadChild1 lockingObj = new ThreadChild1();
lockingObj .start();
synchronized(lockingObj ){
for(int i=1;i<10;i++){
System.out.println("Main "+i);
}
lockingObj.wait();
System.out.println("Main got notified");
}
}
}
class ThreadChild1 extends Thread{
public void run(){
synchronized(this){
for(int i=1;i<10;i++){
System.out.println("Child "+i);
}
this.notify();
}
}
}
Your code is wrong for the reason that you mentioned yourself: you can't be sure which thread goes first.
There are other things that could go wrong - wait can wake up without a notify.
You can read about it in the Javadoc for the wait method, which also explains what you should do:
As in the one argument version, interrupts and spurious wakeups are
possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
In your code, you can solve it with a boolean variable that expresses the condition "I was notified":
public class ThreadExample1 {
public static void main(String[] args) throws InterruptedException {
ThreadChild1 lockingObj = new ThreadChild1();
lockingObj.start();
synchronized (lockingObj) {
for(int i = 1; i < 10; i++) {
System.out.println("Main " + i);
}
while (!lockingObj.haveNotified) {
lockingObj.wait();
}
System.out.println("Main got notified");
}
}
}
class ThreadChild1 extends Thread{
private boolean haveNotified;
public void run(){
synchronized (this) {
for (int i = 1; i < 10; i++) {
System.out.println("Child " + i);
}
haveNotified = true;
this.notify();
}
}
}
While this works correctly on your system, it is not a guranty as your suspicion might become true on a different system. Threading behavior is verry difficult/impossible to predict. Therefore I like to think in worst case scenarios, and if I can come up with a possible breaking situation (as you just described one) I simply redesign to make sure it will work.
A nice trick to test your code is to suspend/pause threads on critical moments by either adding a breakpoint in your IDE, adding a verry time consuming task/call if possible (not failsafe), or by fysically pausing the thread(not always ideal). Besides Im sure there is are libraries to expand on this type of tesing.
I hope this helps you a bit in the right direction.
I have the following piece of code
Boolean flag = new Boolean(false);
flag = true;
Will the second line (assignment) cause a recreation of the initial object (basically a call to new()) in the JVM? I am asking because I am using a Boolean object to synchronize multiple threads, and I am afraid that if a re-initialization takes places, the waiting threads will not see the change in value.
In my application, there are multiple threads that are given a reference to the previous Boolean object. Only one thread changes the objects value to true, and the rest wait until the object's value becomes true. So, if T1 is the thread that changes the value, its code is like:
synchronized(flag) {
flag = true;
flag.notifyAll();
}
and the rest of the threads (T2) will have code like:
synchronized(flag) {
while(flag == false)
wait();
if(flag == true) {
//do something
}
}
Therefore, the question is that after the assignment of true to flag, will the other threads (T2) still have access to the original object?
Thanks,
Nick
The assignment flag = false is a boxing conversion. It will get compiled as flag=Boolean.valueOf(false) which will end up returning the constant Boolean.FALSE.
So the answer is, it will not create a new object but it will change the variable flag as it assigns an instance distinct from your previous result of new Boolean(false).
It’s not quite clear what you are actually doing but in general, synchronizing on a mutable variable is broken design.
The problem is that you are mixing the value that makes up your condition and the object to synchronize on. The simplest implementation of your updated intention is to use a simple boolean flag and synchronize on the instance that contains the flag:
class WithFlag {
private boolean flag;
public synchronized void setToTrue() {
if(!flag) {
flag=true;
notifyAll();
}
}
public synchronized void waitForTrue() throws InterruptedException {
while(!flag) wait();
}
}
Note that declaring an instance method synchronized is similar to wrap its code with synchronized(this) { … }
If you want to use a boolean to synchronize threads, you should consider using AtomicBoolean, which is specifically designed for this purpose.
The other answers have already explained that when you say flag=false, it is a boxing conversion which will return the constant Boolean.FALSE. One important point that the other answers have covered but not emphasized on is that when you obtain a lock on two Boolean objects that were assigned the same value through a boxing conversion, it is as good as obtaining a lock on one Boolean object.
My answer attempts to give an example to explain this. Consider the following code that creates two threads that obtain a lock on a Boolean.
public class BooleanTest {
public static void main(String[] args) {
BooleanTest test = new BooleanTest();
test.booleanTest();
}
private void booleanTest() {
BooleanLockTester booleanLock1 = new BooleanLockTester();
booleanLock1.setBooleanLock(true);
BooleanLockTester booleanLock2 = new BooleanLockTester();
booleanLock2.setBooleanLock(true);
BooleanLocker booleanLocker1 = new BooleanLocker(booleanLock1);
BooleanLocker booleanLocker2 = new BooleanLocker(booleanLock2);
Thread threadOne = new Thread(booleanLocker1);
Thread threadTwo = new Thread(booleanLocker2);
threadOne.start();
threadTwo.start();
}
private class BooleanLocker implements Runnable {
private BooleanLockTester booleanLockObj;
public BooleanLocker(BooleanLockTester booleanLockObj) {
this.booleanLockObj = booleanLockObj;
}
#Override
public void run() {
booleanLockObj.testLockOnBoolean();
}
}
private class BooleanLockTester {
private Boolean booleanLock = false;
public synchronized void testLockOnBoolean() {
synchronized (booleanLock) {
for (int i = 0; i<1000000000; ++i) {
System.out.println(Thread.currentThread().getName());
}
}
}
public void setBooleanLock(Boolean booleanLock) {
this.booleanLock = booleanLock;
}
}
}
In the above example, the two threads will never be able to enter the for loop together. When you run the program, you will see that the thread that starts first will start printing on the console and only when it is finished, the next thread will start printing to the console.
Let's make a small change in the above code :
Change the following line in the code :
booleanLock2.setBooleanLock(true);
To this :
booleanLock2.setBooleanLock(false);
You will now see that the threads stop behaving and print to the console in a random order. This is because the threads now obtain a lock on two different objects.
Well, I was wondering how java handles code reading and running, for example if I wrote:
static void doSomething(){
doSomethingElse();
doYetAnotherThing();
}
Will it wait for doSomethingElse() to complete before it runs doYetAnotherThing()? Or will it just run both?
I guess if it sets a variable, variable = setAVariable(); it will retrieve the variable before continuing, but if the method contains an infinite loop it would get stuck.
Java will run your code sequentially unless u tell it otherwise (by creating threads.)
If you jave an infinite loop in function doSomthingElse() then doYetAnotherThing() will never execute and doSomething will never terminate.
public static void main(String[] args)
{
doSomethingElse();
doYetAnotherThing();
}
private static void doYetAnotherThing() {
System.out.println("Hi Agn");
}
private static void doSomethingElse() {
System.out.println("Hi");
while(true) // Infinite Loop
{
}
}
This will print to output:
Hi
But not: Hi Agn.
For making both functions run you need to remove the infinite loop in doSomethingElse().
UPDATE:
However if you cant do that and still want to run the code above, you can use threads:
Main Class:
public class javaworking
{
static MyThread t1, t2;
Thread tc;
public static void main(String[] args)
{
t1 = new MyThread(1);
Thread tc = new Thread(t1);
tc.start();
t2 = new MyThread(2);
tc = new Thread(t2);
tc.start();
}
}
Thread class that contains all your functions:
public class MyThread implements Runnable {
int ch;
public MyThread(int choice)
{
ch = choice;
}
#Override
public void run() {
// TODO Auto-generated method stub
switch(ch)
{
case 1:
doSomethingElse();
break;
case 2:
doYetAnotherThing();
break;
default:
System.out.println("Illegal Choice");
break;
}
}
private static void doYetAnotherThing() {
// TODO Auto-generated method stub
System.out.println("Hi Agn");
}
private static void doSomethingElse() {
// TODO Auto-generated method stub
System.out.println("Hi");
int i = 1;
while(true)
{
System.out.println(i++);
}
}
}
Please note: The code I provided is merely an example. I didn't do any error handling or follow the recommended standards. The code works and that's it.
Logically the program will read top to bottom. And as a programmer that's all you really need to know. However, behind the scenes this may not necessarily be the case. But you're guaranteed the results as if they ran sequentially.
Sometimes your processor will run lines of code that should never even have been executed! This is because of something called branch prediction(which has a nice explanation on this answer, though not java the idea is demonstrated at a lower level).
Again, you can work under the assumption that everything in the same Thread, will execute in written order.
These are synchronous calls executing in one thread so they are executed one after the other, ie. first doSomethingElse(); then doYetAnotherThing();. If you wanted them to be executed concurrently you could put each in different threads, then the order would not be guaranteed.
One listing from the spec is here:
http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html
The gist is that one function must return before the next one is called. I can't say what that means in your case without knowing what your functions are doing. They could return because they finished or because they forked/spawned off another process/thread/async action. There are more subtleties to this but I'm not getting into anything further than this since they over complicate and obfuscate the answer.
Based on the terminology you use, I would suggest starting with a tutorial. Java doesn't read your code. Java is a language. The compiler will 'read' and parse your code, and generate bytecode that will be executed by the JVM.
And yes, if you cause an infinite loop it's a problem and your program won't exit.
The Following class DoStuff starts a thread and syncs to protect the listener object from being accessed when null.
Now when accessing the DoStuff class function setOnProgressListener() externally I'm having issues because the call is getting held for a long time before it exits the function call. I'm not sure why this happens? I seems as if the synchronization has queued up a lot of calls? Any input on this would help!
I'm essentially passing null to the listener because I no longer wish to get updated for this status. I do this as part of my process to kill the DoStuff Thread.
Thanks!
public class DoStuff extends Runnable
{
Object MUTEX = new Object();
private OnProgressListener mOnProgressListener = null;
public DoStuff()
{
new Thread(this).start();
}
public void setOnProgressListener( OnProgressListener onProgressListener )
{
synchronized (MUTEX)
{
mOnProgressListener = onProgressListener;
}
}
private void reportStatus( int statusId )
{
synchronized (MUTEX)
{
if (null != mOnStatusListener)
{
mOnStatusListener.setStatusMessage(new OnStatusEvent(this, statusId));
}
}
}
// this is the run of a thread
public void run()
{
int status = 0;
do
{
// do some work and report the current work status
status = doWork();
reportStatus( status );
} while(true);
}
}
You should use wait/notify. here is sample;
public class DoStuff {
Object MUTEX = new Object();
String data = null;
public void setData(String data) {
synchronized (MUTEX) {
this.data = data;
System.out.println(Thread.currentThread());
MUTEX.notifyAll();
}
}
public void run() {
do {
synchronized (MUTEX) {
if (null == data) {
return;
} else {
System.out.println(data);
}
try {
MUTEX.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} while (true);
}
}
The trouble with this code is that your while() loop is constantly trying to grab the monitor for MUTEX immediately after releasing it or even yield()-ing to help the scheduler put another thread in. So there's a very good chance that anyone else trying to obtain that monitor will be starved, because your while() loop will consume most of your CPU time and even when other threads could run, they might not get the monitor they're waiting for.
Ideally a wait()/notify() pair should be used or failing that, you should at least call a Thread.yield() in your while loop, outside the synchronized block. (But I this second "solution" really isn't a very good one, you should consider using the first one instead.)
UPDATE: I read the code again and I think I believe to see what you wanted to achieve: printing the value of data every time you set a new value. If that's true, you should definitely go for the wait/notify solution, although if you want to absolutely guarantee that every single value is printed, you need to do even more work, possibly using a queue.
I'm a little confused about your code, can you provide the full listing?
First, where does DoStuff start a thread? Why are you quitting if your data is still null? (you might actually be out of the thread before setData even executes).
But the main thing here is that you're doing essentially a busy-waiting loop, in which you synchronize on the mutex. This is pretty wasteful and will generally block cores of your CPU.
Depending on what you are trying to do, you might want to use a wait-notify scheme, in which the thread goes to sleep until something happens.
Thanks all for your help. I was able to determine why the indefinite lock. Something important and obvious is that once I run the reportStatus() function call it will hold the lock MUTEX until it is completely done executing the callback. My fault was that at the registered callback I was calling setOnProgressListener(null) by mistake. Yes, I admit didn't post enough code, and most likely all of you would have catched the bug... So calling setOnProgressListener(null) would wait until the MUTEX object has been released, and the reportStatus() was held waiting to call setOnProgressListener(null), therefore I was in a deadlock!
Again the main point I learned is to remember that triggering a callback message will hold until the registered callback function is done processing it's call.
Thanks all!