System.out.println("Thread state: " + threads[i].getState());
threads[i].notify();
Produces the following output:
Thread state: WAITING
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at MyPakc.An.run(An.java:49)
at java.lang.Thread.run(Thread.java:679)
What is going on? Why can I not notify a sleeping thread?
EDIT: The code for the threads[] class:
package Part2;
import java.util.List;
import javax.swing.JPanel;
class BThread extends Thread{
private boolean completedThisIter = false;
#Override
public synchronized void run() {
while (true) {
completedThisIter = false;
doStuff()
System.out.println("Completed iter");
completedThisIter = true;
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public boolean getCompletedThisIter() {
return completedThisIter;
}
}
EDIT: Here is the code that calls this
public synchronized void run(){
// OTHER STUFF
for (int iter = 0; iter < 1212; ++iter){
System.out.println("Iter " + iter);
lastAssignedBallIndex = -1;
for (int i = 0; i < numThreads; i++) {
//System.out.println("Num " + numThreads + " " + i);
//ballThreads[i] = new BallThread(ballList.subList(lastAssignedBallIndex+1,lastAssignedBallIndex+numBallsPerThread),
// ballPanel);
//lastAssignedBallIndex += numBallsPerThread;
System.out.println("State " + ballThreads[i].getState());
if (ballThreads[i].getState() == Thread.State.NEW) {
ballThreads[i].start();
} else { //if (ballThreads[i].getState() == Thread.State.BLOCKED) {
System.out.println("Thread state: " + ballThreads[i].getState());
ballThreads[i].notify();
}
}
//try{
for (int i = 0; i < numThreads; i++) {
while (!ballThreads[i].getCompletedThisIter()) {
System.out.println("iter:" + iter + " ball:" + i + " " + ballThreads[i].getCompletedThisIter());
//wait(); // TODO elliminate polling here
}
}
System.out.println("Joined");
//}
// catch(InterruptedException ie){ie.printStackTrace();}
ballPanel.repaint();
notifyAll();
try{
Thread.sleep(2);
}
catch (InterruptedException ie){}
}
}
You're printing out the state of a ballThreads[i] then notifying a threads[i]. Not sure if this is intended behavior but you're not allowed to notify a thread when you don't own the object's monitor. Are you sure you're calling this inside a synchronized() block for the threads[i] object?
EDIT:
Yes, the method that this code is taken out of is synchronized
After your edit to your question, the synchronized is on the method, and not the monitor of the object, you need to put your code in a block that looks like this:
synchronized(threads[i]) {
// some stuff
threads[i].notify();
}
The important bit here (as opposed to the synchronized keyword in a method declaration) is that you synchronize on an Object, then inside this block, you call notify() on the Object. Examples:
public void run()
{
synchronized(myObject) {
// do some stuff
myObject.notify();
}
}
or
public void run()
{
synchronized(thread1) {
// do some stuff
thread1.notify();
}
}
or
public void run()
{
synchronized(syncObject) {
// do some stuff
syncObject.notify();
}
}
See the pattern? More info here: http://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
wait() and notifiy() requires that you synchronize on the object that you are waiting on. if you do a wait() and notify() on the same object that you used to lock the sync block, then you will get rid of the illegal monitor state exception
You are completely misunderstanding the way the wait/notify mechanism works. The thread has to decide that there is something it needs to wait for. Then the thread must call wait. Then that something has to happen. Then you call notify to tell the thread that something happened.
You cannot have the thread call wait without first determining that there is something specific that it should wait for. And you cannot call notify until something has already happened that the thread needs to be notified about. The something that has happened should be the same thing the thread was checking for when it decided to wait.
The reason you are getting in an error is the synchronization associated with the thing waited for simply doesn't exist which violates the semantics of wait/notify.
If you're waiting for a mailbox to be non-empty, then you should check if the mailbox is empty, and if so, call wait. Make sure you are still inside the mailbox's synchronized routine, otherwise you can't know the mailbox is (still) empty. Then when you put a letter in the mailbox (which has to be inside the mailbox's synchronized routine), you call notify to let any waiting threads know the mailbox has changed state. You have to be waiting for something the thread can test, such as the state of the mailbox.
Related
I have 2 matrices and I need to multiply them and then print the results of each cell. As soon as one cell is ready I need to print it, but for example I need to print the [0][0] cell before cell [2][0] even if the result of [2][0] is ready first. So I need to print it by order.
So my idea is to make the printer thread wait until the multiplyThread notifies it that the correct cell is ready to be printed and then the printerThread will print the cell and go back to waiting and so on..
So I have this thread that does the multiplication:
public void run()
{
int countNumOfActions = 0; // How many multiplications have we done
int maxActions = randomize(); // Maximum number of actions allowed
for (int i = 0; i < size; i++)
{
result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
countNumOfActions++;
// Reached the number of allowed actions
if (countNumOfActions >= maxActions)
{
countNumOfActions = 0;
maxActions = randomize();
yield();
}
}
isFinished[rowNum][colNum] = true;
notify();
}
Thread that prints the result of each cell:
public void run()
{
int j = 0; // Columns counter
int i = 0; // Rows counter
System.out.println("The result matrix of the multiplication is:");
while (i < creator.getmThreads().length)
{
synchronized (this)
{
try
{
this.wait();
}
catch (InterruptedException e1)
{
}
}
if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
{
if (j < creator.getmThreads()[i].length)
{
System.out.print(creator.getResult()[i][j] + " ");
j++;
}
else
{
System.out.println();
j = 0;
i++;
System.out.print(creator.getResult()[i][j] + " ");
}
}
}
Now it throws me these exceptions:
Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
line 49 in multiplyThread is the "notify()"..I think I need to use the synchronized differently but I am not sure how.
If anyone can help this code to work I will really appreciate it.
To be able to call notify() you need to synchronize on the same object.
synchronized (someObject) {
someObject.wait();
}
/* different thread / object */
synchronized (someObject) {
someObject.notify();
}
While using the wait and notify or notifyAll methods in Java the following things must be remembered:
Use notifyAll instead of notify if you expect that more than one thread will be waiting for a lock.
The wait and notify methods must be called in a synchronized context. See the link for a more detailed explanation.
Always call the wait() method in a loop because if multiple threads are waiting for a lock and one of them got the lock and reset the condition, then the other threads need to check the condition after they wake up to see whether they need to wait again or can start processing.
Use the same object for calling wait() and notify() method; every object has its own lock so calling wait() on object A and notify() on object B will not make any sense.
Do you need to thread this at all ? I'm wondering how big your matrices are, and whether there's any benefit in having one thread print whilst the other does the multiplication.
Perhaps it would be worth measuring this time before doing the relatively complex threading work ?
If you do need to thread it, I would create 'n' threads to perform the multiplication of the cells (perhaps 'n' is the number of cores available to you), and then use the ExecutorService and Future mechanism to dispatch multiple multiplications simultaneously.
That way you can optimise the work based on the number of cores, and you're using the higher level Java threading tools (which should make life easier). Write the results back into a receiving matrix, and then simply print this once all your Future tasks have completed.
Let's say you have 'black box' application with some class named BlackBoxClass that has method doSomething();.
Further, you have observer or listener named onResponse(String resp) that will be called by BlackBoxClass after unknown time.
The flow is simple:
private String mResponse = null;
...
BlackBoxClass bbc = new BlackBoxClass();
bbc.doSomething();
...
#override
public void onResponse(String resp){
mResponse = resp;
}
Lets say we don't know what is going on with BlackBoxClass and when we should get answer but you don't want to continue your code till you get answer or in other word get onResponse call. Here enters 'Synchronize helper':
public class SyncronizeObj {
public void doWait(long l){
synchronized(this){
try {
this.wait(l);
} catch(InterruptedException e) {
}
}
}
public void doNotify() {
synchronized(this) {
this.notify();
}
}
public void doWait() {
synchronized(this){
try {
this.wait();
} catch(InterruptedException e) {
}
}
}
}
Now we can implement what we want:
public class Demo {
private String mResponse = null;
...
SyncronizeObj sync = new SyncronizeObj();
public void impl(){
BlackBoxClass bbc = new BlackBoxClass();
bbc.doSomething();
if(mResponse == null){
sync.doWait();
}
/** at this momoent you sure that you got response from BlackBoxClass because
onResponse method released your 'wait'. In other cases if you don't want wait too
long (for example wait data from socket) you can use doWait(time)
*/
...
}
#override
public void onResponse(String resp){
mResponse = resp;
sync.doNotify();
}
}
You can only call notify on objects where you own their monitor. So you need something like
synchronized(threadObject)
{
threadObject.notify();
}
notify() needs to be synchronized as well
I'll right simple example show you the right way to use wait and notify in Java.
So I'll create two class named ThreadA & ThreadB. ThreadA will call ThreadB.
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();//<----Create Instance for seconde class
b.start();//<--------------------Launch thread
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();//<-------------WAIT until the finish thread for class B finish
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
and for Class ThreadB:
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();//<----------------Notify the class wich wait until my finish
//and tell that I'm finish
}
}
}
Simple use if you want How to execute threads alternatively :-
public class MyThread {
public static void main(String[] args) {
final Object lock = new Object();
new Thread(() -> {
try {
synchronized (lock) {
for (int i = 0; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + "A");
lock.notify();
lock.wait();
}
}
} catch (Exception e) {}
}, "T1").start();
new Thread(() -> {
try {
synchronized (lock) {
for (int i = 0; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + "B");
lock.notify();
lock.wait();
}
}
} catch (Exception e) {}
}, "T2").start();
}
}
response :-
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
we can call notify to resume the execution of waiting objects as
public synchronized void guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
resume this by invoking notify on another object of same class
public synchronized notifyJoy() {
joy = true;
notifyAll();
}
For this particular problem, why not store up your various results in variables and then when the last of your thread is processed you can print in whatever format you want. This is especially useful if you are gonna be using your work history in other projects.
This looks like a situation for producer-consumer pattern. If you’re using java 5 or up, you may consider using blocking queue(java.util.concurrent.BlockingQueue) and leave the thread coordination work to the underlying framework/api implementation.
See the example from
java 5:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
or java 7 (same example):
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
You have properly guarded your code block when you call wait() method by using synchronized(this).
But you have not taken same precaution when you call notify() method without using guarded block : synchronized(this) or synchronized(someObject)
If you refer to oracle documentation page on Object class, which contains wait() ,notify(), notifyAll() methods, you can see below precaution in all these three methods
This method should only be called by a thread that is the owner of this object's monitor
Many things have been changed in last 7 years and let's have look into other alternatives to synchronized in below SE questions:
Why use a ReentrantLock if one can use synchronized(this)?
Synchronization vs Lock
Avoid synchronized(this) in Java?
I'm programming a little Java program where I need to create threads (philosophers in my code), and these philosophers need to change of state between thinking, hungry and eating.
I'm not that far into the project and I have the next problem:
public class NewMain {
static Philosopher [] p;
public static void main(String[] args) {
p = new Philosopher[5];
p[0] = new Philosopher(0);
p[1] = new Philosopher(1);
p[2] = new Philosopher(2);
p[3] = new Philosopher(3);
p[4] = new Philosopher(4);
for (int i = 0; i<5; i++) {
try{
p[i].run();
if(i == 4) {
p.notifyAll();
}
}
catch(IllegalMonitorStateException e) {}
}
}
}
I'm creating 5 philosophers(threads). Each one of those has a wait() instruction in their code:
#Override
public void run() {
int rand;
if (status == 0) {
System.out.println("Philosopher " + id + " is waiting.");
try {
wait();
System.out.println("Awoken");
while(status == 0) {
System.out.println("Philosopher " + id + " is thinking.");
sleep(100);
rand = ThreadLocalRandom.current().nextInt(0,100);
if(rand > 95){
status = 1;
System.out.println("Philosopher " + id + " changed state to hungry.");
}
}
}
catch(InterruptedException e) {
System.out.println("Error!");
}
catch(IllegalMonitorStateException e) {}
}
}
The problem is that when invoking notifyAll(), the processes don't awake and they just die after executing the run() method of each thread.
If anyone is wondering, I'm not using synchronized because I need to run the methods at the same time.
Also, I've tried to put notifyAll() inside the run() method of the threads.
Can anyone tell me what's going on and why are the threads not continuing
with their code?
Problems
notify[All]() and wait() should be used on the same instance. You are notifying on the array Philosopher[] p, but waiting on this which is a Philosopher. It's like I am waiting for you, but you are notifying Sarah that you're going to be late.
You have created the threads but haven't started them properly. Calling run will execute the method in the current thread. Use the method start instead. It begins execution concurrently.
To use x.notify[All]() or x.wait(), you have to be within a synchronised block synchronized(x) { ... }. Ignoring IllegalMonitorStateException won't help you at all.
Answers
... why are the threads not continuing with their code?
They might call wait after the 4th thread notifies them.
... the processes don't awake and they just die ...
They don't die, they still wait until you terminate the program.
I'm not using synchronizedbecause I need to run the methods at the same time
You need to run the methods at the same time correctly, right? Here, synchronisation is required at least for building wait-notify communication.
p is an array of Runnable. when you write
p[i].run();
Then, you are invoking run method (actually you haven't started a thread here instead called run method) using object stored at p[i] location. Now, as per notifyAll
Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods.
You should have used start() instead run() to start a new thread.
notify() and notifyAll are used when thread(s) are waiting to acquire monitor on current object.
In the code below I have a question regarding what happens after I call wait(). In my code, I am returning a value after calling wait(), what does this actually do? I thought that calling wait() suspends the current thread, but what happens to the value i passed to addWorkItem(Integer i) if wait() is called without returning false? You can see in the producer thread that it adds i to a retry buffer if it couldn't be added to the deque. If I don't return false after wait, does the value i just get lost, or is it still there once the thread wakes up?
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
public class ConsumerProducer2 {
private static int QUEUE_SIZE = 10;
private Deque<Integer> queue = new ArrayDeque<Integer>(QUEUE_SIZE);
public synchronized boolean addWorkItem(Integer i) {
while (queue.size() >= QUEUE_SIZE) {
try {
wait();
return false; // WHAT HAPPENS HERE?
} catch (InterruptedException ex) {}
}
queue.addLast(i);
notify();
return true;
}
public synchronized Integer getWork() {
while (queue.size() == 0) {
try {
wait();
return null; // WHAT HAPPENS HERE?
} catch (InterruptedException ex) {
}
}
Integer i = queue.removeFirst();
notify();
return i;
}
public static void main(String[] args) {
new ConsumerProducer2().go();
}
public void go() {
ConsumerThread ct = new ConsumerThread();
ct.start();
ConsumerThread ct2 = new ConsumerThread();
ct2.start();
ProducerThread pt = new ProducerThread();
pt.start();
}
class ConsumerThread extends Thread {
public void run() {
while(true) {
Integer work = getWork();
if (work == null) {
} else {
System.out.println("Thread: " + this.getId() + " received work: " + work);
}
}
}
}
class ProducerThread extends Thread {
private List<Integer> retryList = new ArrayList<Integer>();
public void run() {
while(true) {
Integer currWork;
if (retryList.size() == 0) {
currWork = (int) (Math.random() * 100);
} else {
currWork = retryList.remove(0);
System.out.println("Thread: " + this.getId() + " retrying old work: " + currWork);
}
if (!addWorkItem(currWork)) {
System.out.println("Thread: " + this.getId() + " could not add work (because buffer is probably full): " + currWork);
retryList.add(currWork);
} else {
System.out.println("Thread: " + this.getId() + " added work to queue: " + currWork);
}
}
}
}
}
Having the producer maintain a retry buffer does keep the i value from getting lost, but this still isn't a good way to write the method.
Returning from inside the while loop doesn't make sense. You check the size of the queue, and if it's maxed out you wait around until you get a notification that the size of the queue changed, then inexplicably return false (??). The waiting doesn't really accomplish anything.
The point of waiting in addWorkItem is to delay your thread until the queue has room for the new value. You should wait inside a loop, where when you come out of the wait, your thread reacquires the lock and re-checks the condition (queue size > max) to see if it can add the item yet.
Once the thread has exited from the while loop it is holding the lock, it is sure there's enough room in the queue for the new item (because no other threads can do anything to change the size of the queue while this thread has the lock held), and it can go ahead and add the value to the queue.
You are catching the InterruptedException in an unproductive way, because you catch it, don't bother to restore the interrupt flag, and go back to the top of the while loop. You should be using the interruption to quit waiting and get out of the method. Letting InterruptedException be thrown here would make more sense; the thread running the method should know better how to handle the interruption than this object does.
You shouldn't assume wait returns only when the thread is notified, it can return without a notification. That's one of the reasons to call wait in a loop.
Reworked version:
public synchronized boolean addWorkItem(Integer i) throws InterruptedException {
while (queue.size() >= QUEUE_SIZE) {
wait();
}
queue.addLast(i);
notify();
return true;
}
If you want an excuse to return false from this you could make the method return false if the queue doesn't make room for the new entry within some time frame (having a timeout can be a good thing in a lot of real-life situations):
public synchronized boolean addWorkItem(Integer i) throws InterruptedException {
final long maxWaitTime = 60L * 1000;
long totalWaitTime = 0;
while (queue.size() >= QUEUE_SIZE && totalWaitTime <= maxWaitTime) {
long waitStartTime = System.currentTimeMillis();
wait(maxWaitTime);
totalWaitTime += (System.currentTimeMillis() - waitStartTime);
}
if (queue.size() >= QUEUE_SIZE) {
return false;
}
queue.addLast(i);
notify();
return true;
}
This will still use the retry buffer (which the first version above it won't do at all), but probably not nearly as much as you are now.
Another thing: you have producer and consumer threads concurrently accessing this, and notify is called for both cases. Since notify only wakes up one thread, it's possible for a thread to get a notification that isn't relevant for it (so the notified thread wakes up, checks its condition and finds it still false, then waits some more, while another thread that the notification actually matters to never finds out about it). There are different ways to solve the problem, you can
assign separate locks, one for producers and one for consumers,
reduce the timeout passed into the wait method so you're less dependent on getting notified, or
you can use notifyAll (less performant but a quick fix).
Have a look at this.
Short story: A waiting thread can be woken up by another one calling notify. So in your case addWorkItem will return false in a thread that called wait() just after another thread calls notify().
Also having a look at your logic I think you are trying to block the consumer when the queue is empty and awake it when there is job to be done.
And you want the producer not to deliver new jobs until the queue is empty.
If this is the case, then calling return after waiting will just close your consumer/producer not letting them finish their jobs when they can.
I'm trying to simulate a simple thermostat, using multi-threading. I have a desired temperature value saved on lblDesiredTemp and another label to display current temperature lblCurrentTemp. The problem occur when while there's more than two active thread in system. the threads which are waiting won't wake up!
this is my method:
'private synchronized void ApplySetting()
{
Thread tempetureUpdater = new Thread()
{
#Override
public synchronized void run()
{
txtLog.setText(txtLog.getText() + "\n" + this.getName());
try
{
while(!isDone)
this.wait();
}
catch (InterruptedException ex)
{
txtLog.setText(txtLog.getText() + "\n" + ex.getMessage());
}
int Max = Integer.parseInt(lblDesiredTemp.getText());
int Current = Integer.parseInt(lblCurrentTemp.getText());
txtLog.setText(txtLog.getText() + "\n" + Current + " to " + Max);
if(Current > Max)
{
isDone = false;
for (int i = Current; i > Max; i--)
{
lblGasStatus.setText("Off");
try
{
Thread.sleep(3000);
decreaseTemeture();
}
catch (InterruptedException ex)
{
txtLog.setText(txtLog.getText() + "\n" + ex.getMessage());
}
}
txtLog.setText(txtLog.getText() + "\n" + this.getName() + " done!");
isDone = true;
this.notifyAll();
}
else
{
isDone = false;
for (int i = Current; i < Max; i++)
{
lblGasStatus.setText("On");
try
{
Thread.sleep(3000);
increaseTemeture();
}
catch (InterruptedException ex)
{
txtLog.setText(txtLog.getText() + "\n" + ex.getMessage());
}
}
txtLog.setText(txtLog.getText() + "\n" + this.getName() + " done!");
isDone = true;
this.notifyAll();
}
// Report the result using invokeLater().
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
setEnabled(true);
}
});
}
};
tempetureUpdater.start();
}
What's the problem?!
The problem occur when while there's more than two active thread in system. the threads which are waiting won't wake up!
Well how would you expect them to? You're only ever notifying the "current" object, which is a new thread. When one thread finishes, it will call this.notifyAll, but that won't wake up other threads.
Additionally, I would strongly urge you to change other things about how you're writing this:
An anonymous inner class of this size is crying out to be broken out into a proper named class
The ApplySetting method name doesn't follow Java naming conventions. Ditto various of your variable names.
It's generally a bad idea to extend Thread - implement Runnable instead, and pass the Runnable to the thread constructor
You shouldn't call wait and notify/notifyAll on Thread objects, as Thread uses that for signalling itself
It's generally a good idea to synchronize on private references which no other code is going to use for synchronization or signalling
As noted in Marko's answer, it's almost always a bad idea to make the run method synchronized. Given the previous bullet point, I prefer not to make any whole methods synchronized, instead synchronizing on individual references within methods
It looks like you're trying to update UI elements within a non-UI thread; I believe that will fail. (You need to use invokeLater)
Never mark the run method as synchronized. Not only here, ever. Also, your notifyAll will attempt to wake up the very thread it runs in. This can't work.
You need to change the this reference in this.wait() and this.notifyAll() so that it refers to the outer object, not the object of your anonymous Thread class. This could be as simple as writing MyClass.this.wait() and MyClass.this.notifyAll(), where MyClass is the class in which your applySettings method is found.
However, I also recommend making the changes listed by Jon Skeet.
I have 2 matrices and I need to multiply them and then print the results of each cell. As soon as one cell is ready I need to print it, but for example I need to print the [0][0] cell before cell [2][0] even if the result of [2][0] is ready first. So I need to print it by order.
So my idea is to make the printer thread wait until the multiplyThread notifies it that the correct cell is ready to be printed and then the printerThread will print the cell and go back to waiting and so on..
So I have this thread that does the multiplication:
public void run()
{
int countNumOfActions = 0; // How many multiplications have we done
int maxActions = randomize(); // Maximum number of actions allowed
for (int i = 0; i < size; i++)
{
result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
countNumOfActions++;
// Reached the number of allowed actions
if (countNumOfActions >= maxActions)
{
countNumOfActions = 0;
maxActions = randomize();
yield();
}
}
isFinished[rowNum][colNum] = true;
notify();
}
Thread that prints the result of each cell:
public void run()
{
int j = 0; // Columns counter
int i = 0; // Rows counter
System.out.println("The result matrix of the multiplication is:");
while (i < creator.getmThreads().length)
{
synchronized (this)
{
try
{
this.wait();
}
catch (InterruptedException e1)
{
}
}
if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
{
if (j < creator.getmThreads()[i].length)
{
System.out.print(creator.getResult()[i][j] + " ");
j++;
}
else
{
System.out.println();
j = 0;
i++;
System.out.print(creator.getResult()[i][j] + " ");
}
}
}
Now it throws me these exceptions:
Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
line 49 in multiplyThread is the "notify()"..I think I need to use the synchronized differently but I am not sure how.
If anyone can help this code to work I will really appreciate it.
To be able to call notify() you need to synchronize on the same object.
synchronized (someObject) {
someObject.wait();
}
/* different thread / object */
synchronized (someObject) {
someObject.notify();
}
While using the wait and notify or notifyAll methods in Java the following things must be remembered:
Use notifyAll instead of notify if you expect that more than one thread will be waiting for a lock.
The wait and notify methods must be called in a synchronized context. See the link for a more detailed explanation.
Always call the wait() method in a loop because if multiple threads are waiting for a lock and one of them got the lock and reset the condition, then the other threads need to check the condition after they wake up to see whether they need to wait again or can start processing.
Use the same object for calling wait() and notify() method; every object has its own lock so calling wait() on object A and notify() on object B will not make any sense.
Do you need to thread this at all ? I'm wondering how big your matrices are, and whether there's any benefit in having one thread print whilst the other does the multiplication.
Perhaps it would be worth measuring this time before doing the relatively complex threading work ?
If you do need to thread it, I would create 'n' threads to perform the multiplication of the cells (perhaps 'n' is the number of cores available to you), and then use the ExecutorService and Future mechanism to dispatch multiple multiplications simultaneously.
That way you can optimise the work based on the number of cores, and you're using the higher level Java threading tools (which should make life easier). Write the results back into a receiving matrix, and then simply print this once all your Future tasks have completed.
Let's say you have 'black box' application with some class named BlackBoxClass that has method doSomething();.
Further, you have observer or listener named onResponse(String resp) that will be called by BlackBoxClass after unknown time.
The flow is simple:
private String mResponse = null;
...
BlackBoxClass bbc = new BlackBoxClass();
bbc.doSomething();
...
#override
public void onResponse(String resp){
mResponse = resp;
}
Lets say we don't know what is going on with BlackBoxClass and when we should get answer but you don't want to continue your code till you get answer or in other word get onResponse call. Here enters 'Synchronize helper':
public class SyncronizeObj {
public void doWait(long l){
synchronized(this){
try {
this.wait(l);
} catch(InterruptedException e) {
}
}
}
public void doNotify() {
synchronized(this) {
this.notify();
}
}
public void doWait() {
synchronized(this){
try {
this.wait();
} catch(InterruptedException e) {
}
}
}
}
Now we can implement what we want:
public class Demo {
private String mResponse = null;
...
SyncronizeObj sync = new SyncronizeObj();
public void impl(){
BlackBoxClass bbc = new BlackBoxClass();
bbc.doSomething();
if(mResponse == null){
sync.doWait();
}
/** at this momoent you sure that you got response from BlackBoxClass because
onResponse method released your 'wait'. In other cases if you don't want wait too
long (for example wait data from socket) you can use doWait(time)
*/
...
}
#override
public void onResponse(String resp){
mResponse = resp;
sync.doNotify();
}
}
You can only call notify on objects where you own their monitor. So you need something like
synchronized(threadObject)
{
threadObject.notify();
}
notify() needs to be synchronized as well
I'll right simple example show you the right way to use wait and notify in Java.
So I'll create two class named ThreadA & ThreadB. ThreadA will call ThreadB.
public class ThreadA {
public static void main(String[] args){
ThreadB b = new ThreadB();//<----Create Instance for seconde class
b.start();//<--------------------Launch thread
synchronized(b){
try{
System.out.println("Waiting for b to complete...");
b.wait();//<-------------WAIT until the finish thread for class B finish
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Total is: " + b.total);
}
}
}
and for Class ThreadB:
class ThreadB extends Thread{
int total;
#Override
public void run(){
synchronized(this){
for(int i=0; i<100 ; i++){
total += i;
}
notify();//<----------------Notify the class wich wait until my finish
//and tell that I'm finish
}
}
}
Simple use if you want How to execute threads alternatively :-
public class MyThread {
public static void main(String[] args) {
final Object lock = new Object();
new Thread(() -> {
try {
synchronized (lock) {
for (int i = 0; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + "A");
lock.notify();
lock.wait();
}
}
} catch (Exception e) {}
}, "T1").start();
new Thread(() -> {
try {
synchronized (lock) {
for (int i = 0; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + ":" + "B");
lock.notify();
lock.wait();
}
}
} catch (Exception e) {}
}, "T2").start();
}
}
response :-
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
we can call notify to resume the execution of waiting objects as
public synchronized void guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
resume this by invoking notify on another object of same class
public synchronized notifyJoy() {
joy = true;
notifyAll();
}
For this particular problem, why not store up your various results in variables and then when the last of your thread is processed you can print in whatever format you want. This is especially useful if you are gonna be using your work history in other projects.
This looks like a situation for producer-consumer pattern. If you’re using java 5 or up, you may consider using blocking queue(java.util.concurrent.BlockingQueue) and leave the thread coordination work to the underlying framework/api implementation.
See the example from
java 5:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html
or java 7 (same example):
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
You have properly guarded your code block when you call wait() method by using synchronized(this).
But you have not taken same precaution when you call notify() method without using guarded block : synchronized(this) or synchronized(someObject)
If you refer to oracle documentation page on Object class, which contains wait() ,notify(), notifyAll() methods, you can see below precaution in all these three methods
This method should only be called by a thread that is the owner of this object's monitor
Many things have been changed in last 7 years and let's have look into other alternatives to synchronized in below SE questions:
Why use a ReentrantLock if one can use synchronized(this)?
Synchronization vs Lock
Avoid synchronized(this) in Java?