Please let me know how I can print “After wait”; how can I notify main thread in the following code:
import java.util.*;
public class Test {
public static void main(String[] args) throws InterruptedException {
ArrayList al = new ArrayList(6);
al.add(0, "abc");
al.add(1, "abc");
al.add(2, "abc");
synchronized(al){
System.out.println("Before wait");
al.wait();
System.out.println("After wait");
}
}
}
The wait() call is blocking until someone notify()s it... Basically, you would need to create a new thread that calls al.notify() when the main thread is blocking in wait().
This program prints Before wait, pauses for one second, and prints After wait.
import java.util.ArrayList;
public class Test {
public static void main(String[] args) throws InterruptedException {
final ArrayList al = new ArrayList(6);
al.add(0, "abc");
al.add(1, "abc");
al.add(2, "abc");
// Start a thread that notifies al after one second.
new Thread() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (al) {
al.notify(); // <-- this "releases" the wait.
}
}
}.start();
synchronized (al) {
System.out.println("Before wait");
al.wait();
System.out.println("After wait");
}
}
}
Here is a link to one of my previous answers, explaining why wait() and notify() must be executed while holding the lock of the monitor.
Why must wait() always be in synchronized block
You're not creating any other threads, so it's hard to see how there is anything else to notify the main thread. However, if you did have another thread which had a reference to al, you'd use something like:
synchronized(al) {
al.notify();
}
or
synchronized(al) {
al.notifyAll();
}
(The difference between the two is that notify will only wake a single thread from waiting; notifyAll will wake all the threads waiting on that object.)
Related
I am trying to print out the content of arraylist using 2 threads, my main goal is to make threads read arraylist in a synchronized way and print its content. Eventhough I use synchronized block, I still am getting IllegalMonitorStateException. I know this is a basic question but I can not get it working, pardon me.
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Q1 {
public static Q1 yeni;
public static void main(String[] args) {
// TODO Auto-generated method stub
yeni = new Q1();
}
Q1() {
List<String> list = Collections.synchronizedList(new ArrayList<String>());
list.add("a1");
list.add("b1");
list.add("c1");
list.add("d1");
list.add("e1");
list.add("f1");
ExecutorService executorService = Executors.newFixedThreadPool(10);
synchronized (list) {
myThread thread1 = new myThread(list);
myThread thread2 = new myThread(list);
thread1.start();
thread2.start();
}
}
}
And here is myThread class
import java.util.*;
public class myThread extends Thread {
List<String> liste;
public myThread(List<String> liste) {
this.liste = liste;
}
#Override
public void run() {
try {
synchronized (Q1.yeni) {
System.out.println("Thread number " + this.getName() + " started running.");
for (int i = 0; i < liste.size(); i++) {
System.out.println(liste.get(i));
this.wait(3000);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The reason for the IllegalMonitorStateException is that you are calling wait on an object (this) without holding the monitor for that object. You must either wrap this call with a synchronized (this) block, or call wait on Q1.yeni, which this code already has synchronized.
However, it looks like the use of wait might be mistaken. This method is used to wait on a condition, which is signaled with a call to notify or notifyAll on the same object. Since there is no apparent condition in this code, and no usages of notify or notifyAll, I suspect that what you really want to call is this.sleep(3000), which pauses the thread for three seconds, then resumes it after that duration elapses.
The sleep method does not require ownership of any monitors, and does not release ownership of held monitors, so another thread would not be able to enter the synchronized (Q1.yeni) block while one is currently sleeping. This implies that the first thread to enter that block will run to completion, iterating through the entire list, before the second thread has a chance to begin. It's not totally clear if that's what is intended here.
See the documentation for Object.wait and Thread.sleep for more usage information.
A second problem is that Q1.yeni is accessed by these threads before it is necessarily initialized, because the threads are started in the Q1 constructor, and the statement yeni = new Q1(); only assigns yeni after the constructor completes. In this case, it might be better for the threads to use synchronized (liste) instead.
Other than that, having synchronized (list) in the Q1 constructor does not accomplish much, since the main thread does not access or manipulate the contents of list in that section. The only practical effect is that the threads it starts will block when they reach the first call to liste.size() until the main thread exits the synchronized (list) (immediately after starting the two threads). This has the potential to slightly slow down the first thread that runs, but has no effect on the thread-safety or correctness of the program.
I would also recommend reviewing "How to Handle InterruptedException in Java". In this case, I would recommend restoring the interruption status in the exception handler.
Put together, here is a revised example of this code (including other minor changes to remove unused code and boilerplate comments, improve formatting, and ensure consistency with Java naming conventions):
Q1.java:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Q1 {
private static Q1 yeni;
public static void main(String[] args) {
yeni = new Q1();
}
Q1() {
List<String> list = Collections.synchronizedList(new ArrayList<>());
list.add("a1");
list.add("b1");
list.add("c1");
list.add("d1");
list.add("e1");
list.add("f1");
MyThread thread1 = new MyThread(list);
MyThread thread2 = new MyThread(list);
thread1.start();
thread2.start();
}
}
MyThread.java:
import java.util.*;
public class MyThread extends Thread {
private final List<String> liste;
public MyThread(List<String> liste) {
this.liste = liste;
}
#Override
public void run() {
try {
synchronized (liste) {
System.out.println("Thread number " + this.getName() + " started running.");
for (int i = 0; i < liste.size(); i++) {
System.out.println(liste.get(i));
sleep(3000);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
interrupt();
}
}
}
Output:
Thread number Thread-0 started running.
a1
b1
c1
d1
e1
f1
Thread number Thread-1 started running.
a1
b1
c1
d1
e1
f1
I have read carefully the Oracle documentation and I could not find a design pattern solution for my issue. I have two anonymous threads and one needs to notify the other.
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.a();
obj.b();
}
The MyClass has two different functions, each one launches an anonymous thread. The B person expects to be woken up by his wife, A.
public class MyClass{
public MyClass(){
}
public void a() {
new Thread(new Runnable(){
#Override
public synchronized void run() {
System.out.println("A: I am going to sleep");
try {
Thread.sleep(1000);
System.out.println("A: I slept one full day. Feels great.");
System.out.println("A: Hey B, wake up!");
notifyAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
public void b() {
new Thread(new Runnable(){
#Override
public synchronized void run() {
System.out.println("B: I am going to sleep. A, please wake me up.");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("B: Thank you A for waking me up!");
}
}).start();
}
}
Unfortunately, B sleeps forever and could not be woken up by his wife, A.
Output of the program:
A: I am going to sleep
B: I am going to sleep. A, please wake me up.
A: I slept one full day. Feels great.
A: Hey B, wake up!
I understand that A and B are running in two different anonymous threads objects, so A could notify only other A (there are not other wife in the bed so the notify function is useless here).
What is the correct design pattern for this issue?
Both threads need to lock using the same semaphore object.
Currently the locks in your code are on two different objects - the Runnable created by a has a lock on the itself and the same with b, so when you call notifyAll there are no object waiting for the lock to notify.
There's also a problem with the Thread.sleep inside the synchronized block.
Change your code so that the lock obtained when the synchronized key word is used like this:
public void a()
{
new Thread(
new Runnable()
{
#Override
public void run()
{
try
{
System.out.println("A: I am going to sleep");
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
synchronized(MyClass.this)
{
System.out.println("A: I slept one full day. Feels great.");
System.out.println("A: Hey B, wake up!");
MyClass.this.notifyAll();
}
}
}
).start();
}
public void b()
{
new Thread(
new Runnable()
{
#Override
public void run()
{
synchronized(MyClass.this)
{
System.out.println("B: I am going to sleep. A, please wake me up.");
try
{
MyClass.this.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("B: Thank you A for waking me up!");
}
}
}
).start();
}
There will need to be a shared ReentrantLock between these threads, perhaps as a class variable. Thread A locks the lock first, then to go to sleep, thread B locks it. Thread A awakens thread B by unlocking the lock. You can also use a semaphore for this.
You need to have a common object shared by the threads to call the wait()/notify() methods on. Now you're calling them on the this object, which in both cases is their own Thread object.
Also note that you need to synchronize on the common object too, so you can't just put synchronized on your run() methods.
The basic point is wait() and notify() or notifyAll() should be called on a single object monitor to have thread synchronization. I would have done something like this
In my code the MyClass has a() and b() instance method synchronized. So the instance on which these methods get invoked will become implicit monitors. I am sharing the same instance of MyClass (which is obj) with 2 Runnable implementations
public class MyClass{
public MyClass(){
}
public synchronized void a() {
System.out.println("A: I am going to sleep");
try {
Thread.sleep(5000);
wait();
System.out.println("A: I slept one full day. Feels great.");
System.out.println("A: Hey B, wake up!");
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void b() {
System.out.println("B: I am going to sleep. A, please wake me up.");
notifyAll();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B: Thank you A for waking me up!");
}
public static void main(String [] args) {
MyClass obj = new MyClass();
Thread t1 = new Thread(new RunnableImpl(obj, true));
Thread t2 = new Thread(new RunnableImpl(obj, false));
t1.start();
t2.start();
}
}
class RunnableImpl implements Runnable {
boolean callA;
MyClass obj;
public RunnableImpl(MyClass obj, boolean callA) {
this.callA = callA;
this.obj = obj;
}
#Override
public void run() {
if(callA) {
obj.a();
}
else {
obj.b();
}
}
}
To be able to wake one thread from another they need to be synchronized with a common object. For example you could use the MyClass object the threads are called from:
public void a() {
new Thread(new Runnable(){
#Override
public synchronized void run() {
System.out.println("A: I am going to sleep");
synchronized(MyClass.this)
{
try {
Thread.sleep(1000);
System.out.println("A: I slept one full day. Feels great.");
System.out.println("A: Hey B, wake up!");
MyClass.this.notifyAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
public void b() {
new Thread(new Runnable(){
#Override
public synchronized void run() {
System.out.println("B: I am going to sleep. A, please wake me up.");
synchronized(MyClass.this)
{
System.out.println("B: Thank you A for waking me up!");
}
}
}).start();
}
This will make a()'s thread acquire the lock and sleep for 1000ms. Meanwhile b() would be called but it's thread would have to wait until a()'s thread releases the lock before it can print Thank you for waking me up.
This would work if you always call a() before b(). Otherwise, if b() acquires the lock first, it's Thank you for waking me up would be executed before a() sleep.
You have two problems in your Code.
As suggested by others . You need to take the same lock for using
notify and wait. You are using different Objects for waiting and notifying which
is their respective thread instances.
Your below code is run use MyClass.this
try {
wait();
} catch (InterruptedException e) {
There is another problem with your code even if you use right locks. Which i
think you try to encounter by Thread.sleep(1000) in thread A. This problem
is called Missed Notifications, i.e. your threadA can complete before your threadB executes its wait() method, this will result in infinite sleep of threadB.
Solution for both the above problem is to use a latch . try CountDownLatch
See below
import java.util.concurrent.CountDownLatch;
public class MyClass{
CountDownLatch latch = new CountDownLatch(1);
public MyClass(){
}
public void a() {
new Thread(new Runnable(){
#Override
public void run() {
System.out.println("A: I am going to sleep");
System.out.println("A: I slept one full day. Feels great.");
System.out.println("A: Hey B, wake up!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}).start();
}
public void b() {
new Thread(new Runnable(){
#Override
public void run() {
System.out.println("B: I am going to sleep. A, please wake me up.");
try {
latch.await();
} catch (InterruptedException e) {}
System.out.println("B: Thank you A for waking me up!");
}
}).start();
}
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.a();
obj.b();
}
}
Am I not using synchronization properly:
In following code i am having 2 problems :
1. while makingmethods (designBusiness,createBusiness,sellBusiness) as synchronized like in this case, a call to wait() says IllegalMonitorStateException but i can not understand why? because in designBusiness method Designer Thread do get a lock so it is supposed to wait on wait call. I am getting IllegalMonitorStateException on wait() and notify() both.
2.Even though when i remove synchronized keyword and use synchronized(this) block for particularly wait() and notify() still i got DEADLOCK! WHY?
public class Main {
HashMap<String, Integer> map = new shop().orderBook();
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
main.sellBusiness();
Thread.sleep(3000);
main.designBusiness();
Thread.sleep(3000);
main.createBusiness();
}
private synchronized void designBusiness() throws InterruptedException {
Thread designThread = new Thread(new Runnable() {
public void run() {
Set set = map.keySet();
System.out.println("Tracking OrderList");
System.out.println(set.size());
try {
System.out.println("waiting.........");
wait();
System.out.println("wait completed");
System.out.println("after design process items in orderList are "
+ map.keySet().size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "Designer Thread");
designThread.start();
System.out
.println("status of Designer Thread" + designThread.isAlive());
}
private synchronized void createBusiness() throws InterruptedException {
Thread createThread = new Thread(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()
+ " started");
Creator creator = new Creator();
creator.create(map);
notifyAll();
System.out.println("notified");
}
}, "Creator Thread");
createThread.start();
createThread.join();
System.out.println("status of Creator Thread" + createThread.isAlive());
}
private void sellBusiness() throws InterruptedException {
Thread sellThread = new Thread(new Runnable() {
public void run() {
Seller seller = new Seller();
seller.sellGold(45000, 15);
seller.sellSilver(14000, 60);
seller.noteOrder("Mrs Johnson", 15000, map);
seller.noteOrder("Mr. Sharma", 10000, map);
seller.sellGold(60000, 20);
seller.noteOrder("Mr. Hooda", 17500, map);
System.out.println(Thread.currentThread().getName()
+ " done selling");
}
}, "Seller Thread");
sellThread.start();
sellThread.join();
System.out.println("status of seller Thread" + sellThread.isAlive());
}
}
please help i could not find any solution for this problem and i am searching from last night.
If you got this exception you are not in a block or method that is synchronised on the object you are waiting on. That is the meaning of the exception. The only meaning.
The wait() method you are calling is executed on the instance of the anonymous inner class you are creating. The synchronised method you are creating it from is synchronised on a different object, and it has probably also already executed by the time the inner object gets to the wait() call.
You need to sort out which object is which here. Probably you need to call Main.this.wait(), but it depends on what you think you're trying to do, which isn't clear from your question.
NB you aren't getting a deadlock, you are getting an infinite block. It isn't the same thing.
wait(), notify() and notifyAll() must be used with synchronized. What I would do is trying to solve the deadlock.
To illustrate why you got deadlock (unrelated code removed) (if I guessed right):
public class Main {
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
main.createBusiness();
}
private synchronized void createBusiness() throws InterruptedException {
// ^^^^^^^^^^^^ got lock
Thread createThread = new Thread(new Runnable() {
public void run() {
synchronized (Main.this) {
// ^^^^^^^^^^^^^^^^^^^^^^^^ try to get lock --> DEADLOCK
Main.this.notifyAll();
}
}
});
createThread.start();
createThread.join();
// ^^^^^^^^^^^^^^^^^^^ wait for createThread to die --> DEADLOCK
}
}
Main thread got the lock of Main.this.
createThread tried to get lock of Main.this, but it's locked by Main.this, hence waiting.
Main thread waited for createThread to die, hence waiting. (2 and 3 can be swapped)
Since I'm not sure what you tried to achieve, I'm not sure if the following is the right solution, but you can try (even if the above guessed wrong):
First, create a lock object.
public class Test {
private Object lock = new Object();
Second, in designer thread
synchronized (lock) {
lock.wait();
}
Third, in creator thread
synchronized (lock) {
lock.notifyAll();
}
wait() must be executed from synchronized block on the same monitor. Since wait() is the same as this.wait() you have to wrap it with synchronized(this):
synchronized(this) {
wait();
}
If you try to unlock an onject by a threas which is not locked by that thread then you may end up with the same error.
If these methods are called from two different threads at the same time, what will be the result?
public class FirstWord {
public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
if(fromSecondWord == false)
SecondWord.writeSecondWord();
System.out.print("Redflex"); }}
public class SecondWord {
public static synchronized void writeSecondWord() throws Exception {
Thread.sleep(100);
FirstWord.writeFirstWord(true);
System.out.print(" Traffic Systems"); }}
Deadlock is very likely in the code sample you have - if you have 2 threads, say ThreadA and ThreadB, then given this scenario:
ThreadA calls FirstWord.writeFirstWord(false) and the thread pauses once inside
ThreadB calls SecondWord.writeSecondWord() and the thread pauses once inside
Now ThreadA continues it'll stop at SecondWord.writeSecondWord(); as ThreadB has the lock SecondWord.
ThreadB can't continue because ThreadA has the lock on FirstWord.
The result is a deadlock.
Note that this isn't the only possible outcome of this code - depending on timing etc the code may run just fine for a while, but its very likely that you'll hit a deadlock at some point.
The result is unpredictable due to the unpredictable nature of sleep().
Also, it depends on how many cores there are, and what parameter you provide in the writeFirstWord(boolean) call.
I'll leave it to you to figure out the details :-)
Hint: one possibility is deadlock.
Example SSCCE (modified):
public class ThreadTest {
public static void main(String[] args) {
new Thread() {
public void run() {
try {
FirstWord.writeFirstWord(false);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
new Thread() {
public void run() {
try {
SecondWord.writeSecondWord(false);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
class FirstWord {
public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
System.out.println("FirstWord start");
Thread.sleep(100);
if (!fromSecondWord) SecondWord.writeSecondWord(true);
System.out.println("FirstWord end");
}
}
class SecondWord {
public static synchronized void writeSecondWord(boolean fromFirstWord) throws Exception {
System.out.println("SecondWord start");
Thread.sleep(100);
if (!fromFirstWord) FirstWord.writeFirstWord(true);
System.out.println("SecondWord end");
}
}
As you can see the console shows:
FirstWord start
SecondWord start
The first thread "enters" into the FirstWord synchronized block while the second one enters the SecondWord one. Then, after sleeping a little bit, the first thread tries to enter into the SecondWord method, and has to wait because the second thread has the lock for that method.
While this happens, the second thread is also waiting to get the other lock, and that's why both threads block and never reach the "end", as they never get both locks.
If you remove Thread.sleep in both methods it may work. As said, it is unpredictable. You can't know which thread is going to enter first.
package com.blt;
public class ThreadsExample implements Runnable {
public static void main(String args[]) {
Thread t=new Thread(new ThreadsExample());
Thread t1=new Thread(new ThreadsExample());
t.start();
t1.start();
}
public void run() {
try {
writeSecondWord();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static synchronized void writeSecondWord() throws Exception {
Thread.sleep(100);
writeFirstWord(true);
System.out.print(" Traffic Systems");
}
public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
if(fromSecondWord == false)
writeSecondWord();
System.out.print("Redflex");
}
}
Output is: Redflex Traffic SystemsRedflex Traffic Systems
Running is above code is fine but there are fair chances that code will produce deadlock at some point of time.
I have two Threads classes "AddThread" and "ReadThread". The execution of these threads should be like this "AddThread should add 1 record and wait until ReadThread displays the record after that ReadThread should display that added record again AddThread should add another record" this process should continue untill all the records are added(REcords are accessed from LinkedList). Here is the code
class AddThread extends Thread
{
private Xml_Parse xParse;
LinkedList commonlist;
AddThread(LinkedList commonEmpList)
{
commonlist = commonEmpList;
}
public void run()
{
System.out.println("RUN");
xParse=new Xml_Parse();
LinkedList newList=xParse.xmlParse();
try
{
synchronized (this) {
if(newList.size()>0)
{
for(int i=0;i<newList.size();i++)
{
System.out.println("FOR");
commonlist.add(newList.get(i));
System.out.println("Added" +(i+1)+ "Record");
}
System.out.println(commonlist.size());
}
}
}
catch(Exception e)
{
}
}
}
class ReadThread extends Thread
{
LinkedList commonlist;
ReadThread(LinkedList commonEmpList)
{
commonlist = commonEmpList;
}
public void run()
{
try
{
synchronized (this) {
System.out.println();
System.out.println("ReadThread RUN");
sleep(1000);
//System.out.println("After waiting ReadThread RUN");
System.out.println(commonlist.size());
if(commonlist.size()>0)
{
for(int j=0;j<commonlist.size();j++)
{
System.out.println("Read For");
System.out.println("EmpNo: "+((EmployeeList)commonlist.get(j)).getEmpno());
System.out.println("EmpName: "+((EmployeeList)commonlist.get(j)).getEname());
System.out.println("EmpSal: "+((EmployeeList)commonlist.get(j)).getEmpsal());
}
}
}
}
catch(Exception e)
{
}
}
}
public class MainThread
{
public static LinkedList commonlist=new LinkedList();
public static void main(String args[])
{
AddThread addThread=new AddThread(commonlist);
ReadThread readThread=new ReadThread(commonlist);
addThread.start();
readThread.start();
}
}
You'll need to learn how to effectively use wait() and notify().
See also:
Guarded Blocks
What about using a BlockingQueue with a capacity of 1? Use offer instead of add so that producer thread is blocked.
You might also consider using a Semaphore with one permit, making it a mutex.
You use join() and yield() to control flux. If you want the current thread to stop and wait until the new thread finishes the work,
t1.run()
t.join()
when t1 finishes t continues.