This question already has answers here:
Why is Java synchronized not working as expected?
(3 answers)
Java synchronized block not working
(2 answers)
Closed 5 years ago.
i have created a JAVA prog to check the working of synchronized block . But it is giving random answers every time. Can anyone explain why it is behaving like that.
Program:
public class ThreadSyncex1 extends Thread {
public static void main(String[] args) {
call a=new call();
call b=new call();
a.start();
b.start();
try {
a.join();
b.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class call extends Thread {
public void run() {
System.out.println(System.currentTimeMillis());
synchronized(this)
{
try {
System.out.println(Thread.currentThread().getName());
System.out.println("Success...");
Thread.sleep(500);
} catch(Exception e){
System.out.println(e);
}
}
}
}
It is giving output :
1502683588129
1502683588129
Thread-1
Thread-0
Success...
Success...
and
1502683592249
1502683592249
Thread-1
Success...
Thread-0
Success...
Related
This question already has answers here:
java when I invoked Thread.sleep(), the data's visibility
(2 answers)
What is the relationship between Thread.sleep and happens-before?
(4 answers)
Closed 22 days ago.
I want to know why Thread.sleep can change the result of this program.Thanks.
this is the question of mine.
When Thread.sleep is running, the program will stop. But else not.
public class Main {
boolean flag = true;
void stop(){
while(flag){
/*
this is the question of mine.
When Thread.sleep running , the programmer will stop . But else not.
*/
//try {
// TimeUnit.MILLISECONDS.sleep(1);
//}catch (Exception ex){
// ex.printStackTrace();
// }
}
System.out.println("over......");
}
public static void main(String[] args) {
Main main = new Main();
new Thread(main::stop).start();
try {
Thread.sleep(1000);
}catch (Exception ex){
ex.printStackTrace();
}
main.flag = false;
}
}
I am trying to print even and odd numbers using two different threads. Can some one point out the mistake I am making.
Currently this is what the output looks like:
Odd: 1
going to wait 1
notify 2
going to wait 2
Please find the code below:
public class EvenOdd {
public static void main(String[] args) {
PrintEvenOdd p1=new PrintEvenOdd(false);
PrintEvenOdd p2=new PrintEvenOdd(true);
p1.start();
p2.start();
}
}
class PrintEvenOdd extends Thread{
boolean isEven;
boolean isOdd=true;
public PrintEvenOdd(boolean e) {
isEven=e;
}
public synchronized void run() {
if(isEven) {
for(int i=2;i<=10;i+=2)
{
while(isOdd) {
try {
System.out.println("going to wait 1");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Even: "+i);
isOdd=true;
System.out.println("notify 1");
notifyAll();
}
}
if(!isEven) {
for(int i=1;i<=10;i+=2) {
while(!isOdd) {
try {
System.out.println("going to wait 2");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Odd: "+ i);
isOdd=false;
System.out.println("notify 2");
notifyAll();
}
}
}
}
As the main idea of your algorithm is not definitely clear for me, I'll just point out where is the bug & you can try to fix it by yourself.
When you start your threads one after another: p1.start(); p2.start(); they are executing in the same order as they we started.
When the first thread calls synchronized void run() method, than it locks the monitor on PrintEvenOdd.class. That means the second thread will wait until the first releases the monitor (say will not execute any single line of code).
Going further in debugger by the first thread execution flow you'll see operations below:
drop down into if(!isEven) condition
set isOdd=false during i=1 loop iteration
goes to endless wait() during i=2 loop iteration
As wait operation does not release the class monitor you're getting situation when both threads are suspended.
I have the following code under my main:
System.out.println(Thread.currentThread().getId());
for(inti=0;i!=Lock.totalThreads;i++) {
System.out.println("thread wascreated");
(new Thread(new MyThread())).start();
}
System.out.println("main finished running files");
MyThread class looks like this:
public class MyThread implements Runnable {
private static int threadCounter=0;
private int myThreadId=0;
#Override
public void run() {
synchronized(Lock.lock){
threadCounter++;
myThreadId=threadCounter;
}
System.out.println("run()");
try {
runMe();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void runMe() throws IOException, InterruptedException {
String currentFile;
BufferedReader in;
System.out.println("run()");
switch(myThreadId){
case 1:
System.out.println("thread1 started");
System.out.println("thread1 finished");
System.out.println(Thread.currentThread().getId());
case 2:
System.out.println("thread2 started");
System.out.println("thread2 finished");
System.out.println(Thread.currentThread().getId());
}
}
And Lock class looks like this:
public class Lock {
public static final Lock lock=new Lock();
public static final int totalThreads=1;
}
And the console output is like this:
1
thread was created
main finished running files
run()
runMe()
thread1 started
thread1 finished
8
thread2 started
thread2 finished
8
I am having troubles to understand how come such a thing happens.
It is obvious (to me at least) that only one time a Thread is created (only once we can see run(), runMe() and thread was created), but twice thread started/finished and the Thread ID in the output.
How come the threadCounter is incremented twice, while entering run() only once?
P.S, I am using Java 6.
You're missing break; after both case 1 and case 2.
I am trying to use 2 threads. 1 thread prints only odd number and the other thread prints only even number and It has to be an alternative operation.
Eg:
Thread1 1
Thread2 2
Thread1 3
Thread2 4
and so on..
Below is the program, please let me know where I am going wrong as the thread1 is not coming out of wait state even when the thread2 is notifying it..
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (t) {
try {
t.notify();
t.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
Problem is that in one case you are taking lock on Thread t [synchronized (t) ] while in other case you are taking lock on TheadA object itself [synchronized(this)].
If you want threads to talk to each other then both should take lock on same object only then wait notify will work as you expect.
Edit:
There is another problem in your program, you are not using any variable to coordinate between 2 threads. SO you may see output like this 2,1,4,3...so on. Point is threads will work alternately but not in sequence.
So you should share a single variable between 2 threads which should be incremented.
Second issue is you are not taking care of spurious wake up calls [read some docs on this], you should always have wait called inside a while loop.
Modified my code based on the answer provided by Lokesh
public class ThreadInteraction {
public static void main(String[] args) {
new ThreadInteraction().test();
}
private void test() {
ThreadA ta = new ThreadA();
Thread t = new Thread(ta);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for(int i=2;i<=50;){
System.out.println("Thread2 "+i);
synchronized (ta) {
try {
ta.notify();
ta.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
class ThreadA implements Runnable{
#Override
public void run() {
for(int i=1;i<50;){
System.out.println("Thread1 "+i);
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i=i+2;
}
}
}
You have a real confusion of threads and locks. I suggest you create one and only one object to use for locking to start with as you don't appear to have a clear idea what you are locking.
If you notify() and nothing is listening, the signal is lost. However, a wait() can wake spuriously.
For this reason, a notify() should be accompanied by a state change and a wait() should be in a loop checking that change.
This question already has answers here:
How does Java's System.exit() work with try/catch/finally blocks? [duplicate]
(6 answers)
Closed 9 years ago.
I have developed a program in which the case of return statement either inside try block or catch block the finally block executes at last but when I write system.exit inside try block in this case the finally block not executed but still I want to execute , could you please advise do I need to add Runtime.getRuntime().addShutdownHook in that case I need to add the code that should be executed in any case , even if system.exit is called. please advise , below is my class
public class Hello {
public static void hello(){
try{
System.out.println("hi");
System.exit(1);
// return;
}catch(RuntimeException e)
{ //return;
}
finally{
System.out.println("finally is still executed at last");
}
}
public static void main(String[] args){
Hello.hello();
}
}
1) in general you do need a shutdown hook if you want to execute some code after exit
public static void main(String[] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
System.out.println("bye");
}
});
hello();
}
2) in this concrete case there's no need for shutdown hook, just remove exit from the code
public static void hello() {
try{
System.out.println("hi");
} catch (RuntimeException e) {
//
} finally{
System.out.println("finally is still executed at last");
}
}
when you are calling System.exit(1)
it exits your program and JVM stops the execution of your program by force .
so why would you use System.exit(1) if you want some code to execute after the exit
simply apply some condition within yout try block to exit try block , which leads to finnaly block in every case