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
Related
This contrived project will eventually deadlock, won't it?
Two methods are synchronized in a shared object. The two threads will eventually find themselves in one of those methods and trying to invoke the other method. I think.
package main;
import java.util.ArrayList;
import java.util.List;
import myThread.MyThread;
import sharedObject.SharedObject;
import uncooperativeThread.UncooperativeThread;
public class Main {
public static void main(String[] args) {
competingThreads();
//uncooperativeThreads();
}
private static void competingThreads() {
List<MyThread> myThreads = new ArrayList<MyThread>();
SharedObject sharedObject = new SharedObject();
int threads = 2;
for (int i = 0; i < threads; i++) {
myThreads.add(new MyThread(i, sharedObject));
}
for (MyThread t : myThreads) {
t.start();
}
for (MyThread t : myThreads) {
try {t.join();} catch (Exception ex) {}
}
}
/**
* We will try to call SharedObject.methodC from two threads. The first one will get in, the second will have to wait.
*/
private static void uncooperativeThreads() {
SharedObject sharedObject = new SharedObject();
UncooperativeThread t1 = new UncooperativeThread(1, sharedObject);
UncooperativeThread t2 = new UncooperativeThread(2, sharedObject);
t1.start();
t2.start();
try {t1.join();} catch (Exception ex) {}
try {t2.join();} catch (Exception ex) {}
}
}
package myThread;
import sharedObject.SharedObject;
public class MyThread extends Thread {
private int id;
SharedObject sharedObject;
public MyThread(int id, SharedObject sharedObject) {
this.id = id;
this.sharedObject = sharedObject; // Reference
}
public void run() {
doStuff();
}
private void doStuff() {
int counter = 0;
while (true) {
System.out.println(++counter);
if (id % 2 == 1) {
sharedObject.methodA(id);
} else {
sharedObject.methodB(id);
}
}
}
}
package sharedObject;
import java.util.Random;
public class SharedObject {
public synchronized void methodA(int id) {
//System.out.println("methodA(): Thread " + id);
try {Thread.sleep((new Random()).nextInt(1000));} catch(Exception ex) {}
if (id == 0) {return;}
// What I want is for one thread to try to call methodB() while the *other* thread is in methodB() trying to call methodA().
methodB(id);
}
public synchronized void methodB(int id) {
//System.out.println("methodB(): Thread " + id);
try {Thread.sleep((new Random()).nextInt(1000));} catch(Exception ex) {}
if (id == 1) {return;}
methodA(id);
}
}
// What I want is for one thread to try to call methodB() while the other thread is in methodB() trying to call methodA().
That's not a deadlock. The thread that's trying to call methodB() simply will be forced to wait until the other thread releases the lock by returning from its methodB() call.
To get a classic deadlock, you need to have two locks. Your program has only one lock—the intrinsic lock belonging to the single instance of SharedObject that your program creates.
A classic deadlock is when one thread has already acquired lock A and is waiting to acquire lock B while the other thread has acquired lock B, and it's waiting to acquire lock A. In that case, neither thread can make progress until the other thread releases its lock. But, neither thread will release its lock because neither thread can make progress.
You need two locks. You have two methods (methodA() and methodB()), but they both lock the same lock.
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();
}
}
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 would like to pause the new tasks from executing. The example provided in the Official Documentation seems to be stopping the currently executed tasks as well (though I am wondering how it does that without interrupting the thread).
class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();
public PausableThreadPoolExecutor(...) { super(...); }
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}
Wrapping the Runnable interface could be easier for this, then you don't have to make your own ThreadPool.
public abstract class PausableRunnable implements Runnable{
private final object _monitor;
public PausableRunnable(object monitor){
_monitor = monitor;
}
#Override
public void Run(){
WaitForNotify();
}
public void WaitForNotify(){
synchronized(_monitor){
while(!done){
_monitor.wait();
}
}
doWork();
}
public abstract void doWork();
}
This could pause new threads easily. Pausing a running thread is a different task, I think this is what you meant. The biggest problem with my solution is if you already want to inherit from something, but it's a starting point
The question was incorrect. The PausablableThreadPoolExecutor does not stop the currently executed thread. Apologies for the incorrect question.
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();
}
}