IllegalMonitorStateException notify() and wait() [duplicate] - java

This question already has answers here:
Java Wait and Notify: IllegalMonitorStateException
(2 answers)
Closed 5 years ago.
I have a problem. When I use notify() in a synchronized block I get IllegalMonitorStateException. Can anyone help me solve this problem?
I need one thread to send a char to a second thread, then this thread has to wait and second thread print this char. After that second thread wait, and first one again sends next char
Main.java:
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
public class Main extends JFrame {
Thread t1, t2;
Consumer con;
public Main() {
con = new Consumer();
startThreads();
}
private synchronized void startThreads() {
t1 = new Thread(new Producent("grudzien", con));
t1.start();
t2 = new Thread(con);
t2.start();
}
public class Producent implements Runnable {
String m_atom;
char[] atoms;
Consumer m_c;
public Producent(String atom, Consumer c) {
m_atom = atom;
m_c = c;
}
#Override
public void run() {
synchronized (this) {
atoms = m_atom.toCharArray();
System.out.print("Tablica znaków: ");
for (int i = 0; i < atoms.length; i++) {
System.out.print(atoms[i] + ", ");
}
}
for (int i = 0; i < atoms.length; i++) {
synchronized (this) {
con.setChar(atoms[i]);
t2.notify();
try {
wait();
} catch (InterruptedException ex) {
JOptionPane.showMessageDialog(null, "Blad w wait()", "Blad!", JOptionPane.ERROR_MESSAGE);
}
}
}
}
}
public class Consumer implements Runnable {
char atom;
public void setChar(char c) {
atom = c;
}
#Override
public void run() {
while (true) {
synchronized (this) {
try {
wait();
} catch (InterruptedException ex) {
JOptionPane.showMessageDialog(null, "Blad w wait()", "Blad!", JOptionPane.ERROR_MESSAGE);
}
System.out.println(atom);
t1.notify();
}
}
}
}
public static void main(String[] args) {
new Main();
}
}

you need to be the "owner of the object's monitor" to be able to call notify on it. so far your methods are all synchronized(this), yet they call notify() on other objects (that they are not synchronized on). in other words:
synchronized(t2) {
t2.notify();
}
and
synchronized(t1) {
t1.notify();
}
for a complete explanation of monitors and synchronization in java, see here, or look for similar questions here on SO, like this one - Java Wait and Notify: IllegalMonitorStateException

Related

why does deadlock not happen

Deadlock describes a situation where two more threads are blocked because of waiting for each other forever. When deadlock occurs, the program hangs forever and the only thing you can do is to kill the program.
why deadlock does not happen in example producer consumer problem given below:
I wonder why call wait method in synchronized block does not causing deadlock when synchronized object is waiting for release of lock from other thread ?
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class WaitAndNotify {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
var th1 = new Thread(new Producer(list));
var th2 = new Thread(new Consumer(list));
th1.start();
th2.start();
}
}
class Producer implements Runnable {
private List<Integer> list;
private final Integer MAX_SIZE_LIST = 5;
public Producer(List<Integer> list) {
this.list = list;
}
#Override
public void run() {
Random rand = new Random();
for (;;) {
synchronized (this.list) {
if (list.size() == MAX_SIZE_LIST) { // check list is full or not
try {
System.out.println("list full wait producer");
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
var randNumber = rand.nextInt();
System.out.println("produce number => " + randNumber);
list.add(randNumber);
list.notify();
}
}
}
}
class Consumer implements Runnable {
private List<Integer> list;
public Consumer(List<Integer> list) {
this.list = list;
}
#Override
public void run() {
for (;;) {
synchronized (this.list) {
if (list.size() == 0) {
try {
System.out.println("list empty consumer wait");
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("consume number <= " + list.remove(0));
list.notify();
}
}
}
}
You probably think, that Consumer will block at list.wait() and Producer will block at synchronized (this.list).
It works, because list.wait() releases the ownership of list inside a synchronized block. After wait returns, the thread acquires the ownership again.
See Object.wait()
As we have already discussed here Deadlock did not happen because of the use of synchronized block, list.wait() and list.notify() methods.
Here is a nice example of deadlock : https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

printing alternative output from 2 threads using semaphores

I am learning about the use of semaphores and multi threading in general but am kind of stuck. I have two threads printing G and H respectively and my objective is to alternate the outputs of each thread so that the output string is like this;
G
H
G
H
G
H
Each of the two classes has a layout similar to the one below
public class ClassA extends Thread implements Runnable{
Semaphore semaphore = null;
public ClassA(Semaphore semaphore){
this.semaphore = semaphore;
}
public void run() {
while(true)
{
try{
semaphore.acquire();
for(int i=0; i<1000; i++){
System.out.println("F");
}
Thread.currentThread();
Thread.sleep(100);
}catch(Exception e)
{
System.out.println(e.toString());
}
semaphore.release();
}
}
}
below is my main class
public static void main(String[] args) throws InterruptedException {
Semaphore semaphore = new Semaphore(1);
ClassA clasA = new ClassA(semaphore);
Thread t1 = new Thread(clasA);
ClassB clasB = new ClassB(semaphore);
Thread t2 = new Thread(clasB);
t1.start();
t2.join();
t2.start();
The output I am getting is way too different from my expected result. can anyone help me please? did I misuse the semaphore? any help?
Semaphores can't help you solve such a task.
As far as I know, JVM doesn't promise any order in thread execution. It means that if you run several threads, one thread can execute several times in a row and have more processor time than any other. So, if you want your threads to execute in a particular order you can, for the simplest example, make a static boolean variable which will play a role of a switcher for your threads. Using wait() and notify() methods will be a better way, and Interface Condition will be the best way I suppose.
import java.io.IOException;
public class Solution {
public static boolean order;
public static void main(String[] args) throws IOException, InterruptedException {
Thread t1 = new ThreadPrint("G", true);
Thread t2 = new ThreadPrint("O", false);
t1.start();
t2.start();
t2.join();
System.out.println("Finish");
}
}
class ThreadPrint extends Thread {
private String line;
private boolean order;
public ThreadPrint(String line, boolean order) {
this.line = line;
this.order = order;
}
#Override
public void run() {
int z = 0;
while (true) {
try {
for (int i = 0; i < 10; i++) {
if (order == Solution.order) {
System.out.print(line + " ");
Solution.order = !order;
}
}
sleep(100);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
}
BTW there can be another problem cause System.out is usually an Operation System buffer and your OS can output your messages in an order on its own.
P.S. You shouldn't inherit Thread and implement Runnable at the same time
public class ClassA extends Thread implements Runnable{
because Thread class already implements Runnable. You can choose only one way which will be better for your purposes.
You should start a thread then join to it not vice versa.
t1.start();
t2.join();
t2.start();
As others have pointed out, locks themselves do not enforce any order and on top of that, you cannot be certain when a thread starts (calling Thread.start() will start the thread at some point in the future, but this might take a while).
You can, however, use locks (like a Semaphore) to enforce an order. In this case, you can use two Semaphores to switch threads on and off (alternate). The two threads (or Runnables) do need to be aware of each other in advance - a more dynamic approach where threads can "join in" on the party would be more complex.
Below a runnable example class with repeatable results (always a good thing to have when testing multi-threading). I will leave it up to you to figure out why and how it works.
import java.util.concurrent.*;
public class AlternateSem implements Runnable {
static final CountDownLatch DONE_LATCH = new CountDownLatch(2);
static final int TIMEOUT_MS = 1000;
static final int MAX_LOOPS = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
try {
AlternateSem as1 = new AlternateSem(false);
AlternateSem as2 = new AlternateSem(true);
as1.setAlternate(as2);
as2.setAlternate(as1);
executor.execute(as1);
executor.execute(as2);
if (DONE_LATCH.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
System.out.println();
System.out.println("Done");
} else {
System.out.println("Timeout");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
executor.shutdownNow();
}
}
final Semaphore sem = new Semaphore(0);
final boolean odd;
AlternateSem other;
public AlternateSem(boolean odd) {
this.odd = odd;
}
void setAlternate(AlternateSem other) { this.other = other; }
void release() { sem.release(); }
void acquire() throws Exception { sem.acquire(); }
#Override
public void run() {
if (odd) {
other.release();
}
int i = 0;
try {
while (i < MAX_LOOPS) {
i++;
other.acquire();
System.out.print(odd ? "G " : "H ");
release();
}
} catch (Exception e) {
e.printStackTrace();
}
DONE_LATCH.countDown();
}
}

More than one thread inside synchronized methods? [duplicate]

This question already has answers here:
Entering in block with an Intrinsic Lock
(2 answers)
Closed 8 years ago.
As I red somewhere, when we have synchronized methods, only one thread can use any of those method at the same time. The problem is that I have small peace of code that looks to break this rule, and I hope some of you knows why.
import java.util.Date;
public class SyncTest extends Thread {
private int state;
public static final int STATE_STOP = 10;
public static final int STATE_DO_TASK = 2;
public static final int STATE_FREE = 0;
public void run() {
try {
while(getThisState() != STATE_STOP) {
if(getThisState() == STATE_DO_TASK) {
Thread.sleep(2000);
setState(0);
}
}
}catch(Exception ex) {
ex.printStackTrace();
}
}
public synchronized void setState(int newState) {
this.state = newState;
this.notify();
}
public synchronized int getThisState() {
return this.state;
}
public synchronized void waitForComplete(int timeoutMilisec) {
try {
while( getThisState() != STATE_FREE) {
wait(timeoutMilisec);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
SyncTest syncTest = new SyncTest();
syncTest.start();
syncTest.setState(STATE_DO_TASK);
System.out.println("Start operation: " + new Date());
syncTest.waitForComplete(30000);
syncTest.setState(STATE_STOP);
System.out.println("End operation: " + new Date());
}
}
What we have here is 'waitForComplete' method, that waits until state equals zero. While main thread waits, second thread is sleeping 5 seconds and then calls setState method. This changes 'state' variable to zero, and calls notify what unlocks waiting in main process. That seems to make sense, but the question is: How the hell it is possible that second thread executes 'setState' when on the same time main thread is inside 'waitForComplete' method. Both methods are synchronized, so it should be impossible to execute them simultaneously.
When you call wait() the thread releases its lock on the monitor, so other threads are free to enter the synchronized block.

Why is my release() method not waking my instance?

I've written an example program to demonstrate my problem.
There's a bartender thread and three customer threads.
They run at the same time once created.
The bartender is suppose to serve each customer a drink.
My problem is that the wait() method within the Bartender classes run() method never awakens.
I had intended for the release() method within the run() method of each Customer class to awaken it but it doesn't seem to be working. It never awakens.
How can I go about fixing this?
Thanks to anyone who can offer advice or code snippets.
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Bar {
Semaphore serving;
boolean isServing = false;
public static void main(String[] args) {
Bar bar = new Bar();
bar.run();
}
public void run() {
serving = new Semaphore(1);
Thread bartender = new Thread(new Bartender());
bartender.start();
threadSleep(1000);
Thread customer1 = new Thread(new Customer());
customer1.start();
threadSleep(2000);
Thread customer2 = new Thread(new Customer());
customer2.start();
threadSleep(2000);
Thread customer3 = new Thread(new Customer());
customer3.start();
}
public void threadSleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException ex) {
Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex);
}
}
public class Bartender implements Runnable {
public void run() {
while (true) {
if (serving.availablePermits() == 0) {
synchronized (this) {
try {
System.out.println("Waiting for Customer notify");
wait();
System.out.println("Serve drink");
} catch (InterruptedException ex) {
Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
}
public class Customer implements Runnable {
private boolean customerServed = false;
public void run() {
if (!customerServed) {
synchronized (this) {
try {
serving.acquire();
if (serving.availablePermits() == 0 && !serving.hasQueuedThreads()) {
notify();
isServing = true;
System.out.println("Customer: Recieves drink");
customerServed = true;
serving.release();
isServing = false;
}
} catch (InterruptedException ex) {
Logger.getLogger(Bar.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
}
In class Bartender and class Customer
change synchronized (this) { to synchronized (Bar.this) {
change wait() to Bar.this.wait()
change notify() to Bar.this.notify()
Because two this refer to different object, Bartender never wakes up. And because two Bar.this refer to same object, Bartender will wake up!

Concurrent actions and threads [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I want to concurrently execute two methods, named A and B.
I also want B to wait for A to finish.
How can I achieve such results by implementing threads in Java?
Use Thread#join(). Call it on thread object which death you want to wait for.
The join method allows one thread to wait for the completion of another.
Example from official tutorial:
public class SimpleThreads {
// Display a message, preceded by
// the name of the current thread
static void threadMessage(String message) {
String threadName =
Thread.currentThread().getName();
System.out.format("%s: %s%n",
threadName,
message);
}
private static class MessageLoop
implements Runnable {
public void run() {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try {
for (int i = 0;
i < importantInfo.length;
i++) {
// Pause for 4 seconds
Thread.sleep(4000);
// Print a message
threadMessage(importantInfo[i]);
}
} catch (InterruptedException e) {
threadMessage("I wasn't done!");
}
}
}
public static void main(String args[])
throws InterruptedException {
// Delay, in milliseconds before
// we interrupt MessageLoop
// thread (default one hour).
long patience = 1000 * 60 * 60;
// If command line argument
// present, gives patience
// in seconds.
if (args.length > 0) {
try {
patience = Long.parseLong(args[0]) * 1000;
} catch (NumberFormatException e) {
System.err.println("Argument must be an integer.");
System.exit(1);
}
}
threadMessage("Starting MessageLoop thread");
long startTime = System.currentTimeMillis();
Thread t = new Thread(new MessageLoop());
t.start();
threadMessage("Waiting for MessageLoop thread to finish");
// loop until MessageLoop
// thread exits
while (t.isAlive()) {
threadMessage("Still waiting...");
// Wait maximum of 1 second
// for MessageLoop thread
// to finish.
t.join(1000);
if (((System.currentTimeMillis() - startTime) > patience)
&& t.isAlive()) {
threadMessage("Tired of waiting!");
t.interrupt();
// Shouldn't be long now
// -- wait indefinitely
t.join();
}
}
threadMessage("Finally!");
}
}
What you need is the Future class of Java. It make very simple to access the results of a method that is called asynchronously.
Check the Javadocs http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Future.html for a better explanation.
Cheers
I'm not sure what you mean by "I want B to wait for A to finish", I took it to mean B needs to run after A.
You can do this easily using the ExecutorService, in this example it is a singleThreadExecutorService so it is guaranteed to run B after A.
The only issue is that if A exits with a problem it will not be picked up so you may want to assign a watchdog thread to pick up the status of A using the Future.get method and then schedule B if A is successful.
public static Object a() {
return new Object();
}
public static Object b() {
return new Object();
}
public static class CallA implements Callable<Object> {
public Object call() throws Exception {
return a();
}
}
public static class CallB implements Callable<Object> {
public Object call() throws Exception {
return b();
}
}
public static void main(String[] args) {
final ExecutorService executorService = Executors.newSingleThreadExecutor();
final Future<Object> aFuture = executorService.submit(new CallA());
final Future<Object> bFuture = executorService.submit(new CallB());
try {
aFuture.get();
bFuture.get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
throw new RuntimeException(ex);
}
}
I would recommend that you do not mess about the Threads unless you know what you're doing - it can lead down a dangerous road. Use the Executors provided and you are much less likely to run into concurrency issues.
Here's a sample Two-Threads code fragment you should be able to start with:
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final Queue<Integer> queue;
public Producer(Queue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final Queue<Integer> queue;
public Consumer(Queue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
Integer i = queue.poll();
if (i != null) {
ended = i == End;
System.out.println(i);
}
}
}
}
public void test() throws InterruptedException {
Queue queue = new LinkedBlockingQueue();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
use wait and notify methods on a common object
Class ClassA implements runnable{
Message messageA;
public ClassA(Message messageA){
this.messageA = messageA;
}
public void run(){
//code here
messageA.notify();
}
}
Class ClassB implements runnable{
Message messageA;
public ClassB(Message messageA){
this.messageA = messageA;
}
public void run(){
messageA.wait();
//code here
}
}
public static void main(){
Message message = new Message();// a simplest object here can be String
//ctreate thread of ClassA(message);
//create thread of classB(message);
}
the threadB will wait untill thread A sends a notify on message object.
Use Thread#join() from oracle javadocs here

Categories

Resources