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.
Related
I am using jdk1.8.
This code runs directly into an infinite loop, but if I add the commented code, it will run normally. I have tried a lot of codes, as long as the operation of locking is involved, it can run normally.
public class StateTest {
public static void main(String[] args) {
State state = new State();
new Thread(new Work(state)).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
state.setStart(true);
System.out.println("the main thread is finished");
}
static class State {
private boolean isStart = false;
public boolean isStart() {
return this.isStart;
}
public void setStart(boolean start) {
this.isStart = start;
}
}
static class Work implements Runnable {
private State state;
public Work(State state) {
this.state = state;
}
#Override
public void run() {
int i = 0;
//endless loop
while (!this.state.isStart()) {
i++;
// if open this code,it will be ok
// synchronized (this) {
//
// }
}
System.out.println(String.format("work start run after %s loops", i));
}
}
}
The problem is that a State instance is not thread-safe. If one thread calls setStart and a second thread calls isStart, then the second thread may not see the value that the first one set1.
You are using setStart on a State instance so that one instance can signal a second one to end the loop. If the second thread doesn't see the state change (because of the above) then the loop won't terminate2.
Solutions:
Change setStart and isStart to be synchronized methods.
Declare the isStart field to be volatile.
Instead of writing your own State class, use a standard java.util.concurrent class to do the synchronization; e.g. CountDownLatch (javadoc).
I recommend that you take the time to study the Oracle Java Tutorial Lesson on concurrency:
The Java™ Tutorials: Lesson: Concurrency
1 - The technical explanation for why this can happen is set out in the "Java Memory Model" section of the Java Language Specification. However, the JLS is NOT written in a way that beginners can understand, and that part is particularly difficult.
2 - In fact, the JLS doesn't say whether the change will be seen or not seen. The actual behavior is liable to depend on a range of factors that are outside of the programmer's control.
It is not guaranteed the isStart value update is visible in the newly created thread.
Since multiple threads access the isStart field, you want to mark it as volatile to assure the updated variable value will be written always in the main memory and not the CPU cache.
static class State {
private volatile boolean isEnd = false;
// getters & setters
}
I have doubt in the behaviour of volatile keyword.
public class TestClassI extends Thread {
private volatile int i=5;
boolean flag;
public TestClassI( boolean flag) {
this.i=i;
this.flag=flag;
}
public void run()
{
if(flag)
{
while(true)
{
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
else
{
i=10;
}
}
}
and in main class using as
public class TestMain {
public static volatile int i=5;
public static void main(String args[]) throws InterruptedException
{
TestClassI test= new TestClassI( true);
test.start();
Thread.sleep(1000);
TestClassI test2=new TestClassI( false);
test2.start();
}
}
I expected the value will be like
5
5
5
5
10
10
10
10.
But it is keep on giving 5. But asper nature of volatile value of i should be stored and retrieved from main memory each time. Please explain is there anything wrong in this code?
You have two instances of TestClassI. They each have their own version of i (because it is an instance field). They don't interfere at all with eachother.
The static TestMain.i is not used in the program at all. There is no shared state.
When the object is instantiated with a false flag, the run method initializes i to 10, and returns. i is never printed:
if (flag) {
// irrelevant
}
else {
i = 10;
}
You don't set i=10in your loop, so it will be set as the only action in your thread, but never printed...
volatile variables have no effect in this case because the variable is an int. long and double variables are affected by volatile, they are loaded and stored in one operation that can't be interrupted rather than two, one for each word. So the volatile variables have no effect.
What is happening that produces the unusual output is that the i is not shared among your threads. If you look, there is a separate i for each thread, although there is a static i in the main class. FYI, the i in the main class is left unnoticed by the threads, who don't notice it at all. If you'd like it to work, one simple modification will suffice: make the i variable in the thread static. Not in the main class, in the thread.
I was looking for the ways to exit a method,
i found two methods
System.exit();
Return;
System.exit() - Exits the full program
Return exits current method and returns an error that remaining code are unreachable.
class myclass
{
public static void myfunc()
{
return;
System.out.println("Function ");
}
}
public class method_test
{
public static void main(String args[])
{
myclass mc= new myclass();
mc.myfunc();
System.out.println("Main");
}
}
There is no best way, it depends on situation.
Ideally, there is no need to exit at all, it will just return.
int a() {
return 2;
}
If there is a real need to exit, use return, there are no penalties for doing so.
void insertElementIntoStructure(Element e, Structure s) {
if (s.contains(e)) {
return; // redundant work;
}
insert(s, e); // insert the element
}
this is best avoided as much as possible as this is impossible to test for failure in voids
Avoid system.exit in functions, it is a major side effect that should be left to be used only in main.
void not_a_nice_function() {
if (errorDetected()) {
System.exit(-1);
}
print("hello, world!");
}
this pseudocode is evil because if you try to reuse this code, it will be hard to find what made it exit prematurely.
The best and proper way to exit from method is adding return statement.
System.exit() will shutdown your programm.
if you use system.exit once a thread goes there, it won't come back.
system.exit is part of Design of the Shutdown Hooks API
first of all your code will kill good programmers imagine this code Which is the Best way to exit a method this code example that how a return comes before a System.out.print(); as it becomes unreachable after the return statement lols
the command
System.exit(int status); (status=0 for Normal Exit && status=-1 for abnormal exit
is only used if you want to exactly quit your whole app whereas
the command
return;
is used to get out/return from a method
these two are different in their operations
I am trying to understand the keyword synchronized from the following example
Java Main Method -->
public int methodA(){
Hello h = new Hello();
h.callSomeSynchronizedMethod();
sysout("Main");
return 0;
}
In the Hello Class-->
public synchronized void callSomeSynchronizedMethod(){
Hi h = new Hi();
h.someMethod();
sysout("Hello");
}
In the Hi class
public void someMethod(){
sysout("Hi");
}
So what would be the list of outputs that i will get;
1.) Is it in the order of Hi, Hello and Main ?
2.) What i understand about the synchronized keyword is that it will only execute 1 method and then execute the other, without multi-threading. Is this correct ?
To really understand what synchronized does you need to run the program twice, once synchronized and once not. Also your program should use multiple threads. So here is an example of such a test.
public class Synchro {
public static void main(String args[]){
new Synchro();
}
public Synchro(){
final Moo moo = new Moo();
Thread t = new Thread(new Runnable(){
public void run(){
moo.aMethod("Second");
}
});
t.start();//calling the method in a thread
moo.aMethod("First");//calling the same method from the same object in the main thread
}
class Moo{
public Moo(){
}
public void aMethod(String name){
//this loop just prints slowly so you can see the execution
for(int i = 1; i <= 100; i++){
System.out.println(String.format("%s : %d", name, i));
try{
Thread.sleep(50);
}catch(InterruptedException e){}
}
}
}
}
Now, if you run the above code, noticing that the method is not synchronized, you will see the printout from the two executions of the method interleaved. That is you will see First 1 then Second 1 then First 2 etc.
Now, add the synchronized keyword to the method making it:
public synchronized void aMethod(String name){ ....
and run the code again. This time, one execution of the method completes before the other begins.
The synchronized keyword is only necessary when multiple threads are accessing the very same object.
You would get "Hi", then "Hello", then "Main", yes. The synchronized modifier has nothing to do with the order the methods are called in; and, other than adding a bit of overhead, it does nothing at all when running the code in a single thread. You could run this same test without synchronized and get the same result.
Now, if you ran a similar test where multiple threads were calling these methods, your results would be less determinate.
Synchronized is meant to allow for the more safe execution of code and management of resources in a multi-threaded environment.
http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Hope this helps.
all these methods will be executed in one thread so the answer for the first question is "yes".
synchronized keyword emans that the method can be executed in only one thread at every moment of time. So if you call it from another thread - it will wait till the execution is finished in the first thread.
In Java there is no automatic multithreading: you must explicitly start a thread and pass it a run method that it will execute. Only in that case will the synchronized keyword start to matter, but its meaning is not quite as you understand it: the methods will execute in whatever thread calls them, but while one is executing, another thread will block before it is able to execute a method guarded by the same lock.
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;
}
}