I cannot figure it out, how can I wake up RecursiveTasks, invoked by ForkJoinPool, when these tasks are on hold by wait method. Here is my simple example with the method MainRecursionClass.resume which is incorrect (does not wakes up RecursiveTasks).
public class Program {
public static void main(String[] args) {
Program p = new Program();
final MainRecursionClass mrc = p.new MainRecursionClass();
//Thread outputs integers to simulate work
new Thread() {
public void run() {
mrc.doJob();
}
}.start();
//Thread performs wait and notify on MainRecursionClass object
p.new PauseResume(mrc).start();
}
/**
*
* This class performs suspend and resume operations to the MainRecursionClass class object
*
*/
private class PauseResume extends Thread {
private MainRecursionClass rv;
public PauseResume(MainRecursionClass rv) {
this.rv = rv;
}
#Override
public void run() {
while(!isInterrupted()) {
try {
sleep(4000);
rv.suspend();
sleep(8000);
rv.resume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private class MainRecursionClass {
private boolean pause = false;
private MyRecursive rv;
public void doJob() {
rv = new MyRecursive(0, 100000);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(rv);
}
public void suspend() {
pause = true;
System.out.println("Suspended");
}
/**
* This method is incorrect. It should wake up all MyRecursive instances to continue their work.
*/
public synchronized void resume() {
pause = false;
notifyAll();
System.out.println("Resumed");
}
private class MyRecursive extends RecursiveTask<Object> {
private static final long serialVersionUID = 1L;
private int start;
private int length;
private int threshold = 15;
public MyRecursive(int start, int length) {
super();
this.start = start;
this.length = length;
}
protected void computeDirectly() throws Exception {
for (int index = start; index < start + length; index++) {
//PAUSE
synchronized (this) {
try {
while(pause) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//PAUSE
//some output to simulate work...
System.out.println(index);
Thread.sleep(1000);
}
}
/**
* Recursion
*/
#Override
protected Object compute() {
if (length <= threshold) {
try {
computeDirectly();
} catch (Exception e) {
return e;
}
return null;
}
int split = length / 2;
invokeAll(new MyRecursive(start, split),
new MyRecursive(start + split, length - split));
return null;
}
}
}
}
You should not use wait/notify in the tasks running on a thread pool. If your pool is bounded, then it may cause thread starvation (a form of deadlock). If it is unbounded, too many threads can be created and main memory exhausted.
Instead, you should split your task in 2 (or more) and start subtasks according to their starting conditions. When you want a task to wait(), then refactor it so that current subtask exits, and next subtask is prepared to run.
Finally I came to this solution: I created List<MyRecursive> list = new ArrayList<>(); object in MainRecursionClass and added every MyRecursive instance, created recursively, in the list. The class MyRecursive has new method:
public synchronized void resume() {
notify();
}
When, the method MainRecursionClass.resume(), which wakes up the threads, looks like this:
public void resume() {
System.out.println("Resumed");
pause = false;
for(MyRecursive mr : list) {
if(mr != null)
mr.resume();
}
}
}
Related
I am working on java version upgrade project and I am on the work where I need to replace deprecated methods.
this.stop();
Code USed this method are in ::
ThreadedTestGroup.java::
package utmj.threaded;
import junit.framework.*;
public class ThreadedTestGroup extends ThreadGroup {
private Test test;
private TestResult testResult;
public ThreadedTestGroup(Test test) {
super("ThreadedTestGroup");
this.test = test;
}
public void interruptThenStop() {
this.interrupt();
if (this.activeCount() > 0) {
this.stop(); // For those threads which won't interrupt
}
}
public void setTestResult(TestResult result) {
testResult = result;
}
public void uncaughtException(Thread t, Throwable e) {
if (e instanceof ThreadDeath) {
return;
}
if (e instanceof AssertionFailedError) {
testResult.addFailure(test, (AssertionFailedError) e);
} else {
testResult.addError(test, e);
}
this.interruptThenStop();
}
}
CobcyrrentTestCase.java
package utmj.threaded;
import java.util.*;
import junit.framework.*;
/
public class ConcurrentTestCase extends TestCase {
private TestResult currentResult;
private ThreadedTestGroup threadGroup;
private Hashtable threads = new Hashtable();
private boolean deadlockDetected = false;
private Vector checkpoints = new Vector();
class ConcurrentTestThread extends Thread {
private volatile boolean hasStarted = false;
private volatile boolean hasFinished = false;
ConcurrentTestThread(
ThreadGroup group,
Runnable runnable,
String name) {
super(group, runnable, name);
}
public void run() {
hasStarted = true;
super.run();
finishThread(this);
}
}
public ConcurrentTestCase(String name) {
super(name);
}
public ConcurrentTestCase() {
super();
}
protected void addThread(String name, final Runnable runnable) {
if (threads.get(name) != null) {
fail("Thread with name '" + name + "' already exists");
}
ConcurrentTestThread newThread =
new ConcurrentTestThread(threadGroup, runnable, name);
threads.put(name, newThread);
}
public synchronized void checkpoint(String checkpointName) {
checkpoints.addElement(checkpointName);
this.notifyAll();
}
public boolean checkpointReached(String checkpointName) {
return checkpoints.contains(checkpointName);
}
public boolean deadlockDetected() {
return deadlockDetected;
}
private synchronized void finishThread(ConcurrentTestThread thread) {
thread.hasFinished = true;
this.notifyAll();
}
private ConcurrentTestThread getThread(String threadName) {
return (ConcurrentTestThread) threads.get(threadName);
}
/**
* Returns true if the thread finished normally, i.e. was not inerrupted or stopped
*/
public boolean hasThreadFinished(String threadName) {
ConcurrentTestThread thread = this.getThread(threadName);
if (thread == null) {
fail("Unknown Thread: " + threadName);
}
return thread.hasFinished;
}
public boolean hasThreadStarted(String threadName) {
ConcurrentTestThread thread = this.getThread(threadName);
if (thread == null) {
fail("Unknown Thread: " + threadName);
}
return thread.hasStarted;
}
private void interruptAllAliveThreads() {
threadGroup.interruptThenStop();
}
/**
* Wait till all threads have finished. Wait maximally millisecondsToWait.
* Should only be called after startThreads().
*/
protected void joinAllThreads(long millisecondsToWait) {
Enumeration enum1 = threads.elements();
long remainingMilliseconds = millisecondsToWait;
while (enum1.hasMoreElements()) {
long before = System.currentTimeMillis();
ConcurrentTestThread each =
(ConcurrentTestThread) enum1.nextElement();
try {
each.join(remainingMilliseconds);
} catch (InterruptedException ignored) {
}
long spent = System.currentTimeMillis() - before;
if (millisecondsToWait != 0) {
remainingMilliseconds = remainingMilliseconds - spent;
if (remainingMilliseconds <= 0) {
deadlockDetected = true;
break;
}
}
}
}
public void joinThread(String threadName) throws InterruptedException {
this.joinThread(threadName, 0);
}
public void joinThread(String threadName, long millisecondsToTimeout)
throws InterruptedException {
ConcurrentTestThread thread = this.getThread(threadName);
if (thread == null) {
fail("Unknown Thread: " + threadName);
}
thread.join(millisecondsToTimeout);
}
/**
* Stores the current result to be accessible during the test
*/
public void run(TestResult result) {
currentResult = result;
super.run(result);
}
protected void setUp() throws Exception {
threadGroup = new ThreadedTestGroup(this);
}
/**
* Sleep and ignore interruption
*/
public void sleep(long milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException ignored) {
}
}
/**
* Run all threads and wait for them to finish without timeout
*/
protected void startAndJoinAllThreads() {
this.startAndJoinThreads(0);
}
protected void startThreads() {
threadGroup.setTestResult(currentResult);
Enumeration enum1 = threads.elements();
while (enum1.hasMoreElements()) {
ConcurrentTestThread each =
(ConcurrentTestThread) enum1.nextElement();
each.start();
each.hasStarted = true;
}
Thread.yield();
}
protected void tearDown() throws Exception {
this.interruptAllAliveThreads();
threads = new Hashtable();
checkpoints = new Vector();
deadlockDetected = false;
threadGroup = null;
currentResult = null;
}
public synchronized void waitForCheckpoint(String checkpointName) {
while (!this.checkpointReached(checkpointName)) {
try {
this.wait();
} catch (InterruptedException ignored) {
}
}
}
public synchronized void waitUntilFinished(String threadName) {
while (!this.hasThreadFinished(threadName)) {
try {
this.wait();
} catch (InterruptedException ignored) {
}
}
}
}
I tried to search lot about this but did not got suitable solution so is there anyone who can help me out to replace this.stop() method which is deprecated.
IDE message: The method stop() from the type ThreadGroup is deprecated
There is no single method that replaces stop() from Thread Group but rather a design approach
From the oracle documentation it says
Many uses of stop should be replaced by code that simply modifies
some variable to indicate that the target thread should stop running.
The target thread should check this variable regularly, and return
from its run method in an orderly fashion if the variable indicates
that it is to stop running
Looking at the samples on What should I use instead of Thread.stop?
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
Throughout your thread, you need to check on a thread safe variable (in the example above its blinker) ... when stop is called, it sets the thread to null breaking out of the while loop and returning from run... thereby "stopping" the thread
Well I red a bit of the documentation about why stop() is deprecated and here is the most relevant part :
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply m>odifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.
With those details, I think there is no more a simple way to stop all the threads as stop() did. You might need to modifie the threads so that you have a way to stop them (if it is possible for you).
I have written the following program for inter thread communication ,, which is simply supposed to produce and consume one by one and program should keep running and printing until stopped externally .
package multithreading;
public class WaitNotifyExample
{
private final int asd;
public WaitNotifyExample(int asd)
{
this.asd = asd;
}
public static void main(String[] args)
{
CounterWaitNotifyExample counter = new CounterWaitNotifyExample(0);
Thread t1 = new Thread(new ConsumerWaitNotifyExample(counter));
Thread t2 = new Thread(new ProducerWaitNotifyExample(counter));
t2.start();
t1.start();
}
}
class ConsumerWaitNotifyExample implements Runnable
{
CounterWaitNotifyExample counter;
public ConsumerWaitNotifyExample(CounterWaitNotifyExample counter)
{
this.counter = counter;
}
#Override
public void run()
{
while (true)
{
counter.consume();
}
}
}
class ProducerWaitNotifyExample implements Runnable
{
CounterWaitNotifyExample counter;
public ProducerWaitNotifyExample(CounterWaitNotifyExample counter)
{
this.counter = counter;
}
#Override
public void run()
{
counter.produce();
}
}
class CounterWaitNotifyExample
{
private int counter;
private boolean produced =false;
public CounterWaitNotifyExample(int counter)
{
this.setCounter(counter);
}
public synchronized void consume()
{
if(!produced)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("consumed "+--counter);
produced = false;
notifyAll();
}
public synchronized void produce()
{
if(produced)
{
try
{
wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("produced "+(++counter));
produced = true;
notifyAll();
}
public int getCounter()
{
return counter;
}
public void setCounter(int counter)
{
this.counter = counter;
}
}
but i only get the following output , as application is still running but nothing is printing , meaning , producer and consumer are not executed any further.
produced 1
consumed 0
what Am I doing wrong here conceptually ?
Your producer doesn't have any loop. Only your consumer has.
Also, read the javadoc of wait(). It must always be called inside a loop checking for a condition.
I have two threads. The first changes the value of variable Data. And second one print the value if its value has changed. I am trying to do that second thread just print each time that the variable's value changed, but I don't reach success. Someone can help me?
thread 1
class someservice{
volatile int data;
Boolean Flag = false;
public void mymethod(){
flag = true;
for (Integer i = 1; i < sheet.getRows(); i++) {
data = someMethod(); //this method when called return a new
//value
}
flag = false;
...
}
}
thread 2
Promise p = task {
try {
while (true) {
if (engineService.getFlag()) {
print(someservice.data);
}else{
break;
}
}
} catch(Throwable t) {
...
}
}
Since you mention Promises, I infer you are familiar with future/ promise in +C++11
in java there is a similar approach, with future callable...
public class HW5 {
public static void main(String[] argv) throws InterruptedException, ExecutionException {
FutureTask<Boolean> myFutureTask = new FutureTask<>(new Callable<Boolean>() {
#Override
public Boolean call() throws Exception {
// implement the logic here and return true if everything was
// ok, false otherwise.
Thread.sleep(5000);
System.out.println("dddd");
return System.currentTimeMillis() % 2 == 0;
}
});
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(myFutureTask);
Boolean result = myFutureTask.get();
System.out.println("Done!");
}
}
FutureTask in a class that takes a callable which can return an Object after its job is done... in Order to execute the Future task you can use a Executor service, especifically calling the method execute, since you need to wait for the thread to do the job then is necessary that you call Future.get, that will basically blocks the main thread until the future is done, to verify the result, just read the variable result..
You could use the notify() and notifyAll() methods within thread. Check out this link: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
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!");
}
public synchronized notifyJoy() {
joy = true;
notifyAll();
}
You have to look up more data about Concurrent programming,I can tell you now some basics,well,not so so basic,but i will do my best:
Here,you have a Monitor,it is an abstract concept,in resume,a Monitor is a
class with all it's
method using"syncronized"
as modifier, it means,
that only
one thread
can access
the method
at once.So,
in the
monitor is
the variable
that you
want to print,
and the"flag",
that tells you if
the variable
was modified.Finally,
you can
see the
most important thing,the"wait()"and"notify()"methods,
those method
stops the thread,or"play"
them again.
You ask
here in
the printValue() method, if your variable was changed, if the variable was'nt change, put the thead to sleep with the wait() method, and when the other
method changeValue() is executed, the value is modified, and the notify() method is called, waking up the thread, so, doing all this, you can guarantee three things:
Safety: meaning that the threads will do that you want
Absence of deadlock: meaning that the thread that is put to sleep, will be awake in the future.
Mutex: meaning that only one thread is executing the critical code, for example, the op. "++" is not atomic, is Subdivided inside in more the one action, create a local var, read the var, sum, and asign, so, if more than one thread are in the game, the value may not be consecutive, example:
i = 0;
i ++;
output: 1;
output: 2;
output: 3;
output: 5;
output: 4;
output: 7;
That could happen, and even so, that will happen in the next code, because there a more than one thread executing. Well, this is the way to program with several threads, more or less
public class Monitor {
private int value = 0;
public static boolean valueHasChanged = false;
public synchronized int changeValue(int newValue){
this.value = newValue;
Monitor.valueHasChanged = true;
this.notify();
return this.value + 1;
}
public synchronized void printValue(){
while(!Monitor.valueHasChanged){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(this.value);
Monitor.valueHasChanged = false;
}
public static void main(String[] args) {
Monitor ac = new Monitor();
BClass t1 = new BClass(ac);
AClass t2 = new AClass(ac);
t1.start();
t2.start();
}
public int getValue() {
return this.value;
}
}
Now the threads:
public class AClass extends Thread{
private Monitor ac;
public AClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.printValue();
}
}
}
And finally:
public class BClass extends Thread{
private Monitor ac;
public BClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
int v = 0;
while(true){
this.ac.changeValue(v);
v++; // this sum is not secure, if you want to print an
// ascending order, the code is diferent, I will show in
// above.
}
}
Now, if you want an ordered print:
the monitor will look like:
public class Monitor {
private int value = 0;
public boolean valueHasChanged = false;
private boolean hasPrint = true;
public synchronized void changeValue(int newValue) {
this.value = newValue;
this.valueHasChanged = true;
this.notify();
}
public synchronized void changeValuePlusOne() {
while (!hasPrint) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.value++;
this.valueHasChanged = true;
this.hasPrint = false;
this.notifyAll();
}
public synchronized void printValue() {
while (!this.valueHasChanged) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.value);
this.valueHasChanged = false;
this.hasPrint = true;
this.notifyAll();
}
public static void main(String[] args) {
Monitor ac = new Monitor();
BClass t1 = new BClass(ac);
AClass t2 = new AClass(ac);
t1.start();
t2.start();
}
public int getValue() {
return this.value;
}
}
And the Threads:
public class BClass extends Thread{
private Monitor ac;
public BClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.changeValuePlusOne();
}
}
}
The other Thread look equals:
public class AClass extends Thread{
private Monitor ac;
public AClass(Monitor ac) {
this.ac = ac;
}
#Override
public void run() {
while(true){
this.ac.printValue();
}
}
}
Very recently I've asked this question, but wasn unable to fix this. So I have a thread hunter (2 of them actually), who "goes off to catch wild boars". He stores these boars in a container Fridge. He will continue to do so until his working hours expire. However, in case the Fridge is full he has to wait. The aim is to wait until a wild boar is removed from the fridge, but if it takes more then 5 seconds of waiting test must be terminated. So everything works except one thing. After running test and interrupting these threads, the program still continues to run. So how do I completely terminate/stop these threads?
TEST CLASS (main)
class Test {
public static void main(String[] args) {
test1();
}
public static void test1() {
Fridge fridge = new Fridge(4);
Hunter hunter1 = new Hunter("hunter1", 4, fridge);
Hunter hunter2 = new Hunter("hunter2", 7, fridge);
Thread hunterThread1 = new Thread(hunter1);
Thread hunterThread2 = new Thread(hunter2);
hunterThread1.start();
hunterThread2.start();
try { Thread.sleep(1000); } catch (InterruptedException e) {}
hunterThread1.interrupt();
hunterThread2.interrupt();
System.out.println(fridge.getSize());
System.out.println(hunter1.getWorkTime());
System.out.println(hunter2.getWorkTime());
}
}
HUNTER CLASS
class Hunter extends Worker {
private int workTime;
private Fridge fridge;
public Hunter(String name, int workTime, Fridge fridge) {
super(name);
this.workTime = workTime;
this.fridge = fridge;
}
public int getWorkTime() {
return workTime;
}
public void run() {
while (workTime > 0) {
/** Each hunt takes a random amount of time (1-50 ms) **/
try { Thread.sleep(workGen()); } catch (InterruptedException e) {}
/** Add new wild boars **/
try { fridge.add(new WildBoar()); } catch (InterruptedException e) {}
workTime--;
/** If thread is interupted break the loop **/
if( Thread.currentThread().isInterrupted()){
break;
}
}
}
}
FRIDGE CLASS
import java.util.Stack;
class Fridge extends Storage {
private Stack<WildBoar> boars;
public Fridge(int cap) {
super(cap);
boars = new Stack<WildBoar>();
}
public int getCap() {
return cap;
}
public int getSize() {
return boars.size();
}
public boolean hasFreeSpace() {
if ( boars.size() < cap )
return true;
else
return false;
}
public synchronized void add(WildBoar boar) throws InterruptedException {
/** If there's no free space available wait **/
while ( !hasFreeSpace() ) {
wait();
}
/** Once there's free space available add new item **/
boars.add(boar);
}
public synchronized WildBoar remove() {
return boars.pop();
}
}
ADDITIONAL CLASSES FOR COMPILING:
abstract class Worker implements Runnable {
private String name;
public Worker(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int workGen() {
return 1 + (int)(Math.random() * (50 - 1));
}
}
class WildBoar {
public WildBoar() {}
}
abstract class Storage {
protected int cap;
public Storage(int cap) {
this.cap = cap;
}
public int getCap() {
return cap;
}
}
After you interrupt() the thread which is currently waiting, the native wait method will actually reset the interruption flag. So when you evaluate the isInterrupted() here, it is actually reset and will appear as not interrupted.
if( Thread.currentThread().isInterrupted()){
break;
}
You will have to re-interrupt the thread after an interruption occurs during the waiting
public synchronized void add(Object boar) {
/** If there's no free space available wait **/
while (!hasFreeSpace()) {
try{
wait();
}catch(InterruptedException e){
Thread.currentThread().interrupt();
return; //or rethrow
}
}
/** Once there's free space available add new item **/
boars.add(boar);
}
Currently, the run method in your Hunter thread is discarding interruptions:
try { fridge.add(new WildBoar()); }
catch (InterruptedException e) {}
Thus, nothing happens when you later check for interruptions
if( Thread.currentThread().isInterrupted()){
break;
}
To correct this, you need to set the thread's interrupt status:
try { fridge.add(new WildBoar()); }
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
Summary - ignoring the InterruptedException resets the interrupt status. If you don't or re-throw it or break, then you will need to set the interrupt status manually.
I have this code:
private void doSomething() throws InterruptedException {
WorkerThread w= new WorkerThread(this);
w.start();
synchronized (synchObj) {
while (!isDone) {
synchObj.wait();
}
}
System.out.println("End");
}
Where the calling class implements a method that calls notifyAll() on synchObj when WorkerThread instance is done. Everything works pretty much as expected except the final call to System.out.println("End"); is never called. Why is that?
Edit: Here's the rest of the code:
public class App implements Notifee {
private boolean isDone = false;
private final Object synchObj = new Object();
/**
* #param args
*/
public static void main(String[] args) {
App app = new App();
for (int i = 0; i < 5; i++) {
try {
app.doSomething();
} catch (InterruptedException e) {
System.err.println("Didn't even start");
e.printStackTrace();
}
}
}
private void doSomething() throws InterruptedException {
WorkerThread w= new WorkerThread(this);
w.start();
synchronized (synchObj) {
while (!isDone) {
synchObj.wait();
}
}
System.out.println("End");
}
#Override
public void letMeKnow() {
synchronized (synchObj) {
synchObj.notifyAll();
}
}
}
public class WorkerThread extends Thread {
private Notifee n;
public WorkerThread(Notifee n){
this.n = n;
}
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
n.letMeKnow();
}
}
You are never setting isDone to true. Also you should make it volatile. You probably should add:
#Override
public void letMeKnow() {
isDone = true;
synchronized (synchObj) {
synchObj.notifyAll();
}
}
Edit: If you want to just wait for the worker thread to finish call:
w.join();