As I Know only one thread can execute on a synchronize method on same block but in below producer consumer problem I am able to run both the methods.
Sample Code
import java.util.concurrent.CountDownLatch;
public class VIV {
public static void main(String[] args) throws Exception {
Number no = new Number();
//Same Object is passed
Even ev = new Even(no, 10);
Odd od = new Odd(no, 10);
Thread oddThraed = new Thread(od,"ODD");
oddThraed.start();
Thread evenThraed = new Thread(ev,"Even");
evenThraed.start();
}
}
class Number {
int no;
boolean flag=false;
public synchronized int getEvenNo() {
System.out.println("In Even Method");
// wait block so no other thread can enter on same object synchronized method
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}
if(!flag) {
try {
Thread.sleep(1000);
}catch (Exception e) {
// TODO: handle exception
}
}
no=no+1;
System.out.println(Thread.currentThread().getName()+":"+no);
flag=false;
notify();
return no;
}
public synchronized int getOddNo() {
System.out.println("In ODD Method");
// wait block so no other thread can enter on same object synchronized method
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}
if(flag) {
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}
}
no = no+1;
System.out.println(Thread.currentThread().getName()+":"+no);
flag=true;
notify();
return no;
}
}
class Even implements Runnable {
Number num;
int noOfTime;
Even(Number no, int noOfTime) {
this.num=no;
this.noOfTime=noOfTime;
}
public void run() {
for(int i=0;i<noOfTime;i++) {
num.getEvenNo();
}
}
}
class Odd implements Runnable {
Number num;
int noOfTime;
Odd(Number no, int noOfTime) {
this.num=no;
this.noOfTime=noOfTime;
}
public void run() {
for(int i=0;i<noOfTime;i++) {
num.getOddNo();
}
}
}
OutPut :
In ODD Method
In Even Method
As Only one Number object is created and passed to other classes which are invoking on its two different synchronized methods. Both methods are printing the message after that waiting .
The reason that both methods get executed at the same time is that the wait() method releases the lock. Once your synchronized method calls wait(), the lock is given back, and another thread can invoke another synchronized method on the same object. Don't call wait() inside a synchronized method in this way!
The wait() calls are also the reason that you're getting deadlock. This is what is happening:
The odd method acquires the lock and starts executing.
The odd method prints its first message.
The odd method invokes wait(), which releases the lock and waits to be notified.
The even method can now acquire the lock that's been released.
The even method prints its first message.
The even method invokes wait(), which releases the lock and waits to be notified.
By this point, you're in the middle of both synchronized methods (because wait() releases the lock), and you're deadlocked (because both methods are waiting).
Don't call wait() unless you're quite sure that's what you need. If your wait() is there just to keep it waiting to see if the synchronization can be broken, you might try Thread.sleep() instead, which will pause without releasing any locks. Usually it's enough to declare the relevant methods or blocks as synchronized without needing any wait / notify.
(By the way, it's not a good idea to have a class called Number, because this is a standard JDK class. It's the superclass of Double, Integer, and so on.)
I don't know whether you are trying to achieve this kind of thing, if you are trying to call EVEN & ODD alternatively, then I have modified your code for the same. Have a look at below code :-
public class VIV {
public static void main(String[] args) throws Exception {
TestNumber no = new TestNumber();
// Same Object is passed
Even ev = new Even(no, 10);
Odd od = new Odd(no, 10);
Thread oddThraed = new Thread(od, "ODD");
oddThraed.start();
Thread evenThraed = new Thread(ev, "Even");
evenThraed.start();
}
}
class TestNumber {
int no;
boolean flag = false;
public synchronized int getEvenNo() {
System.out.println("In Even Method");
// wait block so no other thread can enter on same object synchronized
// method
no = no + 1;
System.out.println(Thread.currentThread().getName() + ":" + no);
flag = false;
notify();
try {
wait();
} catch (Exception e) {
// TODO: handle exception
}
if (!flag) {
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
}
return no;
}
public synchronized int getOddNo() {
System.out.println("In ODD Method");
no = no + 1;
System.out.println(Thread.currentThread().getName() + ":" + no);
flag = true;
notify();
// wait block so no other thread can enter on same object synchronized
// method
try {
wait();
} catch (Exception e) {
// TODO: handle exception
}
if (flag) {
try {
wait();
} catch (Exception e) {
// TODO: handle exception
}
}
return no;
}
}
class Even implements Runnable {
TestNumber num;
int noOfTime;
Even(TestNumber no, int noOfTime) {
this.num = no;
this.noOfTime = noOfTime;
}
public void run() {
for (int i = 0; i < noOfTime; i++) {
num.getEvenNo();
}
}
}
class Odd implements Runnable {
TestNumber num;
int noOfTime;
Odd(TestNumber no, int noOfTime) {
this.num = no;
this.noOfTime = noOfTime;
}
public void run() {
for (int i = 0; i < noOfTime; i++) {
num.getOddNo();
}
}
}
Note : As suggested by #chiastic-security Number is already defined in JDK, I have renamed it to TestNumber in this code.
Output :
In ODD Method
ODD:1
In Even Method
Even:2
In ODD Method
ODD:3
In Even Method
Even:4
In ODD Method
ODD:5
In Even Method
Even:6
In ODD Method
ODD:7
In Even Method
Even:8
In ODD Method
ODD:9
In Even Method
Even:10
In ODD Method
ODD:11
In Even Method
Even:12
In ODD Method
ODD:13
In Even Method
Even:14
In ODD Method
ODD:15
In Even Method
Even:16
In ODD Method
ODD:17
In Even Method
Even:18
In ODD Method
ODD:19
In Even Method
Even:20
Related
I'm studying how to synchronize methods and blocks in Java in order to avoid race condition and I tried to solve an exercise in both ways.
The problem is that if I try to use synchronized block everything works fine but with synchronized method it get stuck.
I thought that I could use both way with not really big differences(maybe one of them reduce parallelism in some case but I'm not sure about this). I'm wondering what's wrong in my code and I want to ask If there's any case where It's preferible using synchronized block instead of synchronized method.
//Not working
import java.util.Random;
class MultiplicationTable extends Thread {
private Cont obj;
private int number;
private Random r;
public MultiplicationTable(Cont o, int num) {
obj = o;
number = num;
r = new Random();
start();
}
public void run() {
for (int j = 0; j < 10; j++) {
for (int i = 0; i < number; i++) {
obj.incr();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
System.out.println(Thread.currentThread().getName() + ": " + obj.getVal());
}
try {
Thread.sleep(r.nextInt(2000));
} catch (InterruptedException e) {
}
}
}
class Cont {
private int count = 0;
private boolean available = false;
public synchronized void incr() {
while (available) {
try {
wait();
} catch (InterruptedException e) {
// TODO: handle exception
}
}
available = true;
count++;
notifyAll();
}
public synchronized int getVal() {
while (!available) {
try {
wait();
} catch (Exception e) {
// TODO: handle exception
}
}
available = false;
notifyAll();
return count;
}
}
public class Es3 {
public static void main(String[] args) {
Cont obj = new Cont();
int num = 5;
MultiplicationTable t1 = new MultiplicationTable(obj, num);
MultiplicationTable t2 = new MultiplicationTable(obj, num);
}
}
//Working
import java.util.Random;
class MultiplicationTable extends Thread {
private Cont obj;
private int number;
private Random r;
public MultiplicationTable(Cont o, int num) {
obj = o;
number = num;
r = new Random();
start();
}
public void run() {
synchronized (obj) {
for (int j = 0; j < 10; j++) {
for (int i = 0; i < number; i++) {
obj.incr();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
System.out.println(Thread.currentThread().getName() + ": " + obj.getVal());
}
try {
Thread.sleep(r.nextInt(2000));
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
}
class Cont {
private int count = 0;
public void incr() {
count++;
}
public int getVal() {
return count;
}
}
public class Es3 {
public static void main(String[] args) {
Cont obj = new Cont();
int num = 5;
MultiplicationTable t1 = new MultiplicationTable(obj, num);
MultiplicationTable t2 = new MultiplicationTable(obj, num);
}
}
I don't think this is a dupe because, despite the title, the actual problem is the OP's specific implementation. There's a bug in the code, it's not a question of methods vs. blocks.
The bug in your code is where you try to implement a locking mechanism. In incr(), you wait until available is set to false, which only happens in getVal():
public synchronized void incr() {
while (available) { // <-- bug
try {
wait();
Since your loop only calls incr() without calling getVal(), both threads become stuck after the first call to incr(). (You call getVal() eventually, but only after the inner loop is complete. Both threads are good and stuck by then.)
Solution: AtomicInteger doesn't have weird bugs like this. If you're trying to implement some kind of producer/consumer mechanism, then one of the concurrent queues (like ArrayBlockingQueue) is a better solution.
One significant difference between synchronized method and block is that, Synchronized block generally reduce scope of lock. As scope of lock is inversely proportional to performance, its always better to lock only critical section of code. One of the best example of using synchronized block is double checked locking in Singleton pattern where instead of locking whole getInstance() method we only lock critical section of code which is used to create Singleton instance. This improves performance drastically because locking is only required one or two times.
Synchronized block provide granular control over lock, as you can use arbitrary any lock to provide mutual exclusion to critical section code. On the other hand synchronized method always lock either on current object represented by this keyword or class level lock, if its static synchronized method.
Synchronized block can throw throw java.lang.NullPointerException if expression provided to block as parameter evaluates to null, which is not the case with synchronized methods.
In case of synchronized method, lock is acquired by thread when it enter method and released when it leaves method, either normally or by throwing Exception. On the other hand in case of synchronized block, thread acquires lock when they enter synchronized block and release when they leave synchronized block.
I've got a test on java thread coding but i have some basic problem.. after hours of trying and searching I decided to try there!
I can't understand why my wait is still locked even after my notify :
Here you can find my code:
public class Mymain {
public static void main(String[] args) {
for( int i=0;i<100;i++){
new ThreadClass(i).start();
}
}
}
public class ThreadClass extends Thread {
static boolean ok = false;
int id;
public ThreadClass(int i) {
id = i;
}
public void run() {
System.out.println("Thread start " + id);
Last.toDo(id);
if (id == 5)
try {
waiting();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (id != 5)
awaking();
System.out.println("thread end " + id);
}
private synchronized void awaking() {
// TODO Auto-generated method stub
if (ok) {
System.out.println("i'm " + id + " and i'm Awaking 5");
ok = false;
notify();
System.out.println("I did the notify and i'm " + id);
}
}
private synchronized void waiting() throws InterruptedException {
System.out.println("Sleeping");
ok = true;
wait();
System.out.println("Awake 5");
}
}
Result
Then it starts looping or it goes in dead lock not sure.. it should just stop the thread with id=5 and then the next thread should re-start the id = 5.. but thread 5 never wake up after the notify...
In the result as you can see I got 2 threads trying to wake up the thread 5 and thread 5 is always waiting since the start^^
The issue is that you are not calling notify() on the same object that you called wait() on. In particular, thread 5 is calling wait() on itself, but thread 8, for example, is calling notify() on itself, not on thread 5. As a result, thread 5 is never getting notified.
Also, you need to make the ok variable volatile to ensure that when one thread sets it, the other threads can see the change. This isn't causing you a problem in this particular case, but it could cause a problem in other cases.
Why you don't use notifyAll() method? When you invoke notify(), it means that only one thread will change a status from waiting to runnable, but there can be the situations when you have more than one thread and other threads which are waiting in the line as well, they will not receive this notification. In my opinion it is preferable to use notifyAll.
i can't understand why my wait is still locked even after my notify :
Wait and notify work when the same object instance is used. If you for example have:
String x1 = "...";
String x2 = "...";
and thread #1 does:
synchronized (x1) { x1.wait(); }
and thread #2 then does:
synchronized (x2) { x2.wait(); }
Then thread #1 will still be waiting because the notify was only for x2. In your example, the thread with id 5 is waiting on its own instance of ThreadClass since you are using method synchronization. Then when other threads call awaking() they too are calling notify on their instances of ThreadClass. If you want thread #5 to see the other thread's notify then they should share a lock object.
Maybe something like:
final Object lock = new Object();
for (int id = 0; id < 100; id++){
new ThreadClass(id, lock).start();
}
...
public class ThreadClass extends Thread {
private final Object lock;
...
public ThreadClass(int id, Object lock) {
this.id = id;
this.lock = lock;
}
...
private void awaking() {
...
synchronized (lock) {
lock.notify();
}
...
}
private void waiting() throws InterruptedException {
...
synchronized (lock) {
lock.wait();
}
...
}
}
Look I did a few changes to your code:
You can't just notify() , you'll notify to this. And you can't just wait() , you'll wait forever. You have to use these function over an Object, so i added an Integer object (just to show you - you'll have to choose the right object).
You have yo understand between synchronized and static synchronized. A quick search would lead you to a perfect answer.
Why function waiting() is synchronized? only thread number 5 calls it.
When calling to an Object.notify() / Object.wait(), you have to declare a synchronized block over the object.
Here's some code:
public class Threads {
public static void main(String[] args) {
Integer intObject = new Integer(0);
for( int i=0;i<100;i++){
new ThreadClass(i, intObject).start();
}
}
}
class ThreadClass extends Thread {
static boolean ok = false;
int id;
Integer intObject;
public ThreadClass(int i, Integer intObject) {
id = i;
this.intObject = intObject;
}
public void run() {
System.out.println("Thread start " + id);
//Last.toDo(id);
if (id == 5)
waiting();
else
awaking(this);
System.out.println("thread end " + id);
}
private static synchronized void awaking(ThreadClass t) {
if(ok) {
System.out.println("i'm " + t.id + " and i'm Awaking 5");
ok = false;
synchronized (t.intObject) {
t.intObject.notify();
}
System.out.println("I did the notify and i'm " + t.id);
}
}
private void waiting(){
System.out.println("Sleeping");
ok = true;
synchronized (intObject) {
try {
intObject.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Awake 5");
}
}
I know this question has been asked before, But I am unable to figure out why my solution is not working for me. I have two threads even and odd, one prints even numbers and other prints odd numbers. When I start the threads I want the output to be in natural order of numbers like 0 1 2 3..etc. This is my code:-
[updated]
public class ThreadCommunication {
public static void main(String... args) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread(){
#Override
public void run()
{
for(int i=0;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
obj.notify();
}
}
}
};
even.start();
odd.start();
}
}
when I run the above code, sometimes it prints the numbers in natural order as expected but sometimes it prints in some other order for ex:
0
1
3
5
7
9
2
What am I doing wrong here?
Edit:
volatile static boolean isAlreadyWaiting = false;
Thread even = new Thread() {
#Override
public void run() {
synchronized (obj) {
for (int i = 0; i < 10; i = i + 2) {
System.out.println(i);
try {
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
obj.notify();
isAlreadyWaiting=false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread() {
#Override
public void run() {
synchronized (obj) {
for (int i = 1; i < 10; i = i + 2) {
System.out.println(i);
try {
if(isAlreadyWaiting){
obj.notify();
isAlreadyWaiting = false;
}
if (!isAlreadyWaiting) {
isAlreadyWaiting = true;
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Check documentation
public class IllegalMonitorStateException extends RuntimeException
Thrown to indicate that a thread has attempted to wait on an object's
monitor or to notify other threads waiting on an object's monitor
without owning the specified monitor.
Monitor is owned by obj
So you should call
obj.wait();
and
obj.notify();
For more info on Ownership
This methods (wait or notify) should only be called by a thread that
is the owner of this object's monitor. A thread becomes the owner of
the object's monitor in one of three ways:
By executing a synchronized instance method of that object.
By executing the body of a synchronized statement that synchronizes
on the object.
For objects of type Class, by executing a synchronized static method
of that class.
Only one thread at a time can own an object's monitor.
#Pragnani Kinnera is right about the exception you're seeing. But if you want to alternate between even and odd, you'll need to move your second synchronized block into the loop. Otherwise, the notifying thread will hold the lock exclusively until the loop completes. (As opposed to the first thread, which yields its lock on each round.)
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
synchronized(obj){
System.out.println(i);
notify();
}
}
}
};
The first thread, however, should have the loop inside the synchronized block. If both threads release the lock, they both have an equal chance at reacquiring it. But if the first loop is inside the synchronized block, the second thread won't be able to reenter until the first has completed a full round and is waiting once again.
EDIT: This still won't work correctly, because there is no guarantee that the first thread won't reacquire the lock before the second thread does, per this quote from the documentation:
The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
You'll probably want to wake and notify from both threads to ensure they're in sync.
Here is your solution:
public class ThreadCommunication {
public static void main(String args[]) throws InterruptedException
{
final ThreadCommunication obj = new ThreadCommunication();
Thread even = new Thread("Even Thread"){
#Override
public void run()
{
for(int i=0;i<10;i=i+2){
System.out.println(i);
synchronized(obj){
obj.notify();
}
synchronized(obj){
try {
obj.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread odd = new Thread(){
#Override
public void run()
{
for(int i=1;i<10;i=i+2){
try {
synchronized(obj){
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
synchronized(obj){
obj.notifyAll();
}
}
}
};
even.start();
odd.start();
}
}
As explained by #shmosel, your synchronized block should only contain code that need to be synchronized.
I have written some Java code, which will call a C interrupt handler.
In Java thread A, I use waitFor() to wait the interrupt coming and then execute reboot.
In Java thread B, I will loop printing a counter value and sleep several milliseconds.
And I hope when I detect the interrupt, and then stop the printing in thread B at once, but failed. In fact, the system detects the interrupt in time, but the printing continues for maybe 10 seconds and then reboot. Note: reboot occurs maybe 11 seconds after the interrupt(press a button), the hardware is not fast.
Below is my code, any suggestion? Thanks!
import java.io.IOException;
class ThreadTesterA implements Runnable
{
private int counter;
private String cmds[] = new String[1];
private Process pcs;
#Override
public void run()
{
cmds[0] = "./gpio-interrupt";
try {
pcs = Runtime.getRuntime().exec(cmds);
if(pcs.waitFor() != 0) {
System.out.println("error");
} else {
ThreadTesterB.setClosed(true);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ThreadTesterB implements Runnable
{
private int i;
private static boolean closed=false;
public static void setClosed(boolean closed)
{
closed = closed;
}
#Override
public void run()
{
// replace it with what you need to do
while (!closed) {
System.out.println("i = " + i);
i++;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println();
}
}
public class ThreadTester
{
public static void main(String[] args) throws InterruptedException
{
Thread t1 = new Thread(new ThreadTesterA());
Thread t2 = new Thread(new ThreadTesterB());
t1.start();
t1.setPriority(Thread.MAX_PRIORITY);
//t1.join(); // wait t1 to be finished
t2.start();
//t2.join();
}
}
You're writing and reading a boolean variable (closed) from 2 different threads without any kind of synchronization. There is thus no guarantee that what you wrote in one thread is visible in the other thread. You need to either
make the boolean variable volatile
access the boolean variable (writing and reading) using blocks or methods synchronized on the same lock
use an AtomicBoolean instead of a boolean
I would use the third solution.
public class thread extends Thread {
static volatile boolean done = false;// volatile keyword is used
#Override
public void run() {
while (!done) {
for (int i = 1; i < 10; i++) {
try {
thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currentThread());
System.out.println("1st thread>> " + i);
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread th = new Thread(new thread(),"mythread");
th.start();
for (int i = 1; i < 10; i++) {
thread.sleep(400);
System.out.println(currentThread());
System.out.println("2nd thread>> " + i);
if (i == 4) {
done = true;// safe way to stop a thread
break;
}
}
}
}
I am using volatile static variable here.Is it a safe way to stop a thread and also
when I print currentThread() method I get the output like Thread[mythread,5,main]
what does the 5 and main refer to??
It's a safe way to stop a thread, but there is no reason for the variable to be static: you want to stop one thread, not all threads of the same class.
Moreover, there is a more standard and less fragile way to stop a thread: interrupting it.
public void run() {
while (!Thread.currentThread().isInterrupted() {
...
}
}
...
th.interrupt();
This has the additional advantage that a thread which is sleeping or waiting, or blocked in an interruptible IO method will be woken up with an InterruptedException. When such an exception happens, it means that the thread should stop running, so you shouldn't swallow the exception as you did. Instead, you should return from the run method as fast as possible:
try {
thread.sleep(200);
}
catch (InterruptedException e) {
return;
}
Thread to toString, which is what is being called when you do System.out.println(currentThread()) prints out the thread name, priority, and thread group.
I'm assuming you are trying to interrupt the thread for something other then a normal completion, so why not just use Thread.interrupt() and Thread.isInterrupted()?