class Lock
{
public int l=0;
}
class Numbers extends Thread
{
final Lock lock;
Numbers(Lock l,String name)
{
super(name);
lock=l;
}
public void run()
{
synchronized(lock)
{
for(int i=0;i<100;i++)
{
if(i==50)
{
try
{
while(lock.l==0)
{
System.out.println("Waiting for letters to complete");
wait();
System.out.println("Wait complete");
}
}
catch(InterruptedException e)
{
System.err.println("ERROR");
}
}
System.out.println(i);
}
}
}
}
class Letters extends Thread
{
final Lock lock;
Letters(Lock l,String name)
{
super(name);
lock=l;
}
public void run()
{
synchronized(lock)
{
for(int i=65;i<=90;i++)
System.out.println((char)i);
lock.l=1;
notify();
}
}
}
public class MyClass
{
public static void main(String args[])
{
Lock l=new Lock();
Numbers n=new Numbers(l,"Numbers");
Letters let=new Letters(l,"Letters");
n.start();
let.start();
}
}
What I intend through this program is to print the numbers up to 49 and then wait till the Letters thread finishes printing letters and then the control goes back to Numbers thread and finishes execution.
But this code throws exception after printing numbers up to 49 then prints A-Z and then fails to execute showing IllegalMonitorStateException.
fails to execute showing IllegalMonitorStateException.
This results from the fact that the call to the notify(); method is not obeying to the its contract:
Wakes up a single thread that is waiting on this object's monitor.
(...)
This method should only be called by a thread that is the owner of
this object's monitor.
and the same applies for the wait method:
This method should only be called by a thread that is the owner of this object's monitor.
TL:DR
You are calling wait and notify() on the wrong lock (i.e., the implicit lock of the instance return by this).
Change, respectively, those calls to:
lock.notify(); and lock.wait();
Running Example based on your code:
class Lock{
public int l=0;
}
class Numbers extends Thread
{
final Lock lock;
Numbers(Lock l,String name){
super(name);
lock=l;
}
public void run() {
synchronized(lock) {
for(int i=0;i<100;i++){
if(i==50){
try {
while(lock.l==0){
System.out.println("Waiting for letters to complete");
lock.wait();
System.out.println("Wait complete");
}
}
catch(InterruptedException e){
System.err.println("ERROR");
}
}
System.out.println(i);
}
}
}
}
class Letters extends Thread {
final Lock lock;
Letters(Lock l,String name)
{
super(name);
lock=l;
}
public void run()
{
synchronized(lock){
for(int i=65;i<=90;i++)
System.out.println((char)i);
lock.l=1;
lock.notify();
}
}
}
class MyClass {
public static void main(String args[]) {
Lock l=new Lock();
Numbers n=new Numbers(l,"Numbers");
Letters let=new Letters(l,"Letters");
n.start();
let.start();
}
}
Related
So I implanted Mutex to pause and resume thread but when I start the thread with the implemented Mutex outer thread stop executing till the inner thread finish. I am not sure where I am wrong. I create an interface to get the lock value and use it as boolean for if statement. So basically when the custom thread run the inner thread freeze till the inner thread is not finished. I need to not stop.In two words, I need to pause the thread and resume it later. In // do my code here comment field I am using function which have a loop inside, I am not sure if this is the problem.
Interface:
public interface Thread {
Mutex getMutex();
void run();
}
Thread example:
public class CustomThread extends Thread implements ThreadInterface{
private final Mutex mutex;
public CustomeThread() {
this.mutex = new Mutex(false);
}
public Mutex getMutex() {
return this.mutex;
}
#Override
public void run() {
while (!isInterrupted()) {
mutex.step();
// Do my code here
}
}
}
Starting the thread in another thread:
public class ThreadingUtil {
public void threadRunner(List<CustomThread> threadList) throws InterruptedException {
if (threadList.size() > 1) {
Random random = new Random();
while(threadList.size() > 0) {
int index = random.nextInt(threadList.size());
CustomThread thread = threadList.get(0);
if(thread.getMutex().isLock().get()) {
thread.getMutex().unlock();
} else {
thread.run();
}
// Code stop here after run the thread
Thread.sleep(20000);
thread.getMutex().lock();
System.out.println("thread mus be locked next thread");
}
}
}
Running outer thread:
thread = new Thread(new Runnable() {
#Override
public void run() {
try {
threadingUtil.threadRunner(threadList);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
thread.start();
Mutex:
public class Mutex {
private final AtomicBoolean lock;
private final Object mutex;
public Mutex(boolean lock) {
this.lock = new AtomicBoolean(lock);
this.mutex = new Object();
}
public void step() {
if (lock.get()) synchronized (mutex) {
try {
mutex.wait();
} catch (InterruptedException ex) {
}
}
}
public void lock() {
lock.set(true);
}
public AtomicBoolean isLock() {
return this.lock;
}
public void unlock() {
lock.set(false);
synchronized (mutex) {
mutex.notify();
}
}
}
EDIT: I start the thread with implementing start() method in the Thread interface now its not blocking the thread but the getMutex().lock() is not stopping the thread now.
EDIT: in run method make sure to not place inner loop i the while loop since is not pausing the inner loop
I have 2 threads, one calls get() method, another put() method.
I need to synchronize this methods in order to see result of get only after put. I do know how to do this other way, but I want to understand why am i getting .IllegalMonitorStateException with this code.
public class TransferObject {
private int value;
protected volatile boolean isValuePresent = false; //use this variable
public synchronized int get() {
synchronized (TransferObject.class) {
System.out.println("Got: " + value);
notify();
}
return value;
}
public void put(int value) {
synchronized (TransferObject.class) {
this.value = value;
System.out.println("Put: " + value);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Here is example of 2 threads.
public class ConsumerTask implements Runnable {
private TransferObject transferObject;
protected volatile boolean stopped;
public ConsumerTask(TransferObject transferObject) {
this.transferObject = transferObject;
new Thread(this, "ConsumerTask").start();
}
public void run() {
while (!stopped) {
transferObject.get();
}
}
public void stop() {
stopped = true;
}
}
public class ProducerTask implements Runnable {
private TransferObject transferObject;
protected volatile boolean stopped;
static volatile AtomicInteger i = new AtomicInteger(0);
public ProducerTask(TransferObject transferObject) {
this.transferObject = transferObject;
new Thread(this, "ProducerTask").start();
}
public void run() {
while (!stopped) {
transferObject.put(i.incrementAndGet());
}
}
public void stop() {
stopped = true;
}
}
You have two threads and one object for locking TransferObject.class.
When your thread ConsumerTask gets the lock, object TransferObject.class don't have sleeping threads, and when you call notify() for this monitor you get IllegalMonitorStateException
From the description for method notify:
Wakes up a single thread that is waiting on this object's monitor.
You don't have waiting treads for monitor TransferObject.class
I encountered the issue like the Deadlocks and Synchronized methods. In this case, methodA, methodB, A.last() all must be the synchronized method. So I am going to resolve this issue by removing synchronized in the method B.last(). Any deadlock in this solution? Could you please let me know any solution to resolve this better?
Class A
{
synchronized void methodA(B b)
{
b.last();
}
synchronized void last()
{
System.out.println(“ Inside A.last()”);
}
}
Class B
{
synchronized void methodB(A a)
{
a.last();
}
synchronized void last()
{
System.out.println(“ Inside B.last()”);
}
}
Class Deadlock implements Runnable
{
A a = new A();
B b = new B();
// Constructor
Deadlock()
{
Thread t = new Thread(this);
t.start();
a.methodA(b);
}
public void run()
{
b.methodB(a);
}
public static void main(String args[] )
{
new Deadlock();
}
}
In general, to avoid deadlocks, either use only one lock at all, or make sure that locks are always acquired in the same order.
Assuming that you decide A always has to be locked before B, a minimally invasive bugfix for your example (assuming that nothing else synchronizes against A or B objects) would be this in class B:
void methodB(A a) {
synchronized(a) {
synchronized(this) {
// do whatever was in methodB before, including...
a.last();
}
}
}
That way, if both locks are required, lock of A is always acquired first, causing no deadlocks.
You can also do the same with the Java 5+ java.util.concurrent locks. Removing a synchronized where not needed is of course also an option to solve the deadlock (but if synchronization was needed, it will cause race conditions instead which are usually worse than a deadlock).
You can use a common mutex such as a ReentrantLock or synchronized blocks between the two methods instead of synchronized.
ReentrantLock example:
Class A
{
A(Lock lock) {
this.lock = lock;
}
private Lock lock;
void methodA(B b)
{
lock.lock();
try {
b.last();
} finally {
lock.unlock();
}
}
void last()
{
lock.lock();
try {
System.out.println(“ Inside A.last()”);
} finally {
lock.unlock();
}
}
}
Class B
{
B(Lock lock) {
this.lock = lock;
}
private Lock lock;
void methodB(A a)
{
lock.lock();
try {
a.last();
} finally {
lock.unlock();
}
}
void last()
{
lock.lock();
try {
System.out.println(“ Inside B.last()”);
} finally {
lock.unlock();
}
}
}
Class Deadlock implements Runnable
{
Lock lock = new ReentrantLock();
A a = new A(lock);
B b = new B(lock);
// Constructor
Deadlock()
{
Thread t = new Thread(this);
t.start();
a.methodA(b);
}
public void run()
{
b.methodB(a);
}
public static void main(String args[] )
{
new Deadlock();
}
}
synchronized block example:
Class A
{
A(Object lock) {
this.lock = lock;
}
private Object lock;
void methodA(B b)
{
synchronized(lock){
b.last();
}
}
void last()
{
synchronized(lock){
System.out.println(“ Inside A.last()”);
}
}
}
Class B
{
B(Object lock) {
this.lock = lock;
}
private Object lock;
void methodB(A a)
{
synchronized(lock){
a.last();
}
}
void last()
{
synchronized(lock){
System.out.println(“ Inside B.last()”);
}
}
}
Class Deadlock implements Runnable
{
Object lock = new Object();
A a = new A(lock);
B b = new B(lock);
// Constructor
Deadlock()
{
Thread t = new Thread(this);
t.start();
a.methodA(b);
}
public void run()
{
b.methodB(a);
}
public static void main(String args[] )
{
new Deadlock();
}
}
I am having a trouble to share a resource with three threads...
public class Subject{
int i;
boolean valueSet1 = false;
boolean valueSet2 = true;
boolean valueSet3 = true;
void put(int i){
while(valueSet1){
try{
wait();
}catch(InterruptedException e){
System.out.println("Producer thread interrupted");
}
}
System.out.println("Producer thread wakesup");
valueSet1=true;
valueSet2=false;
this.i=i;
System.out.println("Put: "+i);
notify();
}
void makesquare(){
int a;
while(valueSet2){
try{
System.out.println("Convertor thread goin to sleep");
wait();
}catch(InterruptedException e){
System.out.println("Convertor thread interrupted");
}
}
System.out.println("Convertor thread wakesup");
valueSet2 = true;
valueSet3=false;
a = this.i;
this.i = a*a;
System.out.println("Made: "+i);
notify();
}
void get(){
while(valueSet3){
try{
System.out.println("Consumer thread goin to sleep");
wait();
}catch(InterruptedException e){
System.out.println("Consumer thread interrupted");
}
}
System.out.println("Consumer thread wakesup");
valueSet3 = true;
valueSet1 = false;
System.out.println("Got: "+i);
notify();
}
}
class Producer implements Runnable{
Subject q;
Thread t;
String msg;
Producer(Subject q, String msg){
this.q=q;
this.msg = msg;
t = new Thread(this, this.msg);
}
#Override
public void run(){
int i=2;
while(true){
synchronized(q){
q.put(i++);
}
}
}
}
class Consumer implements Runnable{
Subject q;
Thread t;
String msg;
Consumer(Subject q,String msg){
this.q = q;
this.msg = msg;
t = new Thread(this, this.msg);
}
#Override
public void run(){
while(true){
synchronized(q){
q.get();
}
}
}
}
class Convertor implements Runnable{
Subject q;
Thread t;
String msg;
Convertor(Subject q, String msg){
this.q=q;
this.msg = msg;
t = new Thread(this, this.msg);
}
#Override
public void run(){
while(true){
synchronized(q){
q.makesquare();
}
}
}
}
There are three threads in the program. One thread produces while another makes square of the produced quantity. While the last thread consumes the squared product.They all share the same object.
public class Thread3way {
public static void main(String[] args) {
Subject q = new Subject();
Producer P = new Producer(q, "producer");
Convertor Cv = new Convertor(q, "convertor");
Consumer Cs = new Consumer(q, "consumer");
P.t.start();
Cv.t.start();
Cs.t.start();
}
}
Your wait loop is not quite correct, you need to keep looping until your condition is true before you do any modifications. I'd do it like this (using a State enum to make things clearer):
public class Subject {
static enum State { EMPTY, WAITING_TO_SQUARE, WAITING_TO_GET };
State state;
int value;
public synchronized void put(int i) {
while (state != State.EMPTY) {
try {
wait();
}catch(InterruptedException e) {
System.out.println("Put interrupted");
}
}
value = i;
state = State.WAITING_TO_SQUARE;
}
}
As a commenter pointed out, you don't need to synchronize twice, either synchronized(q) around the Subject calls, or declare your methods synchronized. You don't need both.
No need to use Runnables explicitly, just make Producer, Convertor, and Consumer Threads directly. Then you don't need the t fields, and you can start the threads like P.start().
Sounds to me like you're doing some kind of pipeline with 3 stages. Why not enjoy the benefits of ExecutorService:
class ConvertorTask implements Runnable {
private int number;
private static ExecutorService consumer = Executors.newSingleThreadExecutor();
public ConvertorTask(int number) {
this.number = number;
}
public void run() {
consumer.submit(new ConsumerTask(number * number));
}
}
class ConsumerTask implements Runnable {
private int number;
public ConsumerTask(int number) {
this.number = number;
}
public void run() {
System.out.println(number);
}
}
class Producer implements Runnable {
private ExecutorService convertor = Executors.newSingleThreadExecutor();
public void run() {
int i = 0;
while(true) {
convertor.submit(new ConvertorTask(i++));
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Producer());
t.start();
}
}
Consider the following piece of code -
class MyThread extends Thread {
private int x = 5;
public void run() {
synchronized (this) // <-- what does it mean?
{
for (int i = 0; i < x; i++) {
System.out.println(i);
}
notify();
}
}
}
class Test {
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
synchronized (m) {
try {
m.wait();
} catch (InterruptedException e) {
}
}
}
}
In the above example, does Thread m acquire the lock on itself?
The current thread acquires the lock on the associated instance of the MyThread class.
The synchronized(this) is locking the same object as synchronized(m) in main().
Finally,
public void run() {
synchronized (this) {
is exactly equivalent to
public synchronized void run() {
Yes, that's exactly what it means. The thread acquires a lock on the instance of the class (MyThread).
You have to see it as any other java object. what you have typed means that other threads can't access this java object (independently if it was a thread instance or not because it doesn't make difference.