How to use notifyAll for a specific thread? - java

Okay so this is the code. It basically has three classes. One of them is increasing a value and the other one decreasing with an endless loop. But when the value goes over or under a specific limit, it has to stop. But since both of the functions have notifyAll, it wakes the other functions as well so even if it is at the limit, it keeps going. How can I solve this problem? Thanks in advance.
First Class (increasing and with Thread):
public class Producer extends Thread{
private Counter counter;
public Producer(Counter counter) {
// TODO Auto-generated constructor stub
this.counter=counter;
}
#Override
public void run() {
// TODO Auto-generated method stub
//super.run();
for(;;) {
try {
counter.increase();
sleep(100);
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("Producer:"+e.getMessage());
}
}
}
The second class (decreasing with Runnable):
public class Consumer implements Runnable{
private Counter counter;
public Consumer(Counter counter) {
// TODO Auto-generated constructor stub
this.counter=counter;
}
#Override
public void run() {
// TODO Auto-generated method stub
//super.run();
for(;;) {
try {
counter.decrease();
Thread.currentThread().sleep(100);
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("Consumer:"+e.getMessage());
}
}
}
}
Third class which contains the functions:
import java.util.Random;
public class Counter {
private int counter;
private Random ran;
public Counter() {
//super();
counter=0;
ran= new Random();
}
public synchronized void increase() {
int number=ran.nextInt(5);
if(counter+number>=100 ) {
System.out.println("Producer is stopping, value is: "+counter);
System.out.println("The generated number is: "+number);
try {
wait();
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("error in increasing mehtod"+e.getMessage());
}
}
counter = counter+number;
notifyAll();
System.out.println("Prdoucer increase: "+counter);
}
public synchronized void decrease() {
int number= ran.nextInt(5);
if(counter-number<0) {
System.out.println("Consumer is stopping, value is: "+counter);
System.out.println("The generated number is: "+number);
try {
wait();
}
catch (InterruptedException e) {
// TODO: handle exception
System.out.println("error in decreasing mehtod"+e.getMessage());
}
}
counter = counter-number;
notifyAll();
System.out.println("Consumer decrease: "+counter);
}
}

Read about spurious notifies. A thread can be notified even without explicit call to notify()/notifyAll(). So after each notify the thread must check if it was indeed notified, and be ready to find out it was notified in vain.

.How to use notifyAll() for a specific thread.
You don't. That's not what notifyAll() is for, and it's not what notify() is for either.
You use notify() and/or notifyAll() to notify other threads that some particular thing has changed or happened. You use notify() when it's guaranteed that any single thread that catches the notification will be able to deal with whatever it was that changed or happened. You use notifyAll() otherwise.
In neither case does the caller get to specify which thread or threads should be notified. The system will randomly chose any single thread that happens to be waiting in an o.wait() call if you call o.notify() for the same object o, or it will notify all of the threads that happen to be waiting in o.wait() if you call o.notifyAll(). It won't do anything for threads that aren't already in an o.wait() call at the moment when o.notify() or o.notifyAll() was called.
It's up to you to write code that exploits those functions to your advantage. There's plenty of examples and tutorials out there for how to do that. My personal favorite: https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
Also note: Correctly usage of notify() and notifyAll() is somewhat tricky. It's tricky for you to write it correctly, and it's tricky for other people who want to read and understand your code.
If you think you need notify() or notifyAll() the first thing you should do is consider whether or not you could use some higher-level class that encapsulates the notify/wait behavior. E.g., for a "producer/consumer" architecture, you might consider using a BlockingQueue.

Related

Synchronized block still locked after thread restart

I try to restart thread but synchronized block in thread keep locked after restarted. I shouldn't change socket properties because some processes take too long but when network connection lost it hangs forever. I try to use InterruptedException but it doesn't work. Is there any way to release this lock?
public static void main(String[] args) {
try {
synchronizedBlock t1 = new synchronizedBlock();
t1.start();
Thread.sleep(500);
t1.cancel();
t1 = new synchronizedBlock();
t1.start();
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
}
}
public class synchronizedBlock extends Thread {
boolean isRunning = true;
boolean isRunning2 = true;
public static Object[] locks = new Object[5];
public synchronizedBlock() {
for (Integer i = 0; i < 5; i++) {
synchronizedBlock.locks[i] = i;
}
}
public void cancel() {
isRunning = false;
interrupt();
}
public void socketProces() {
while (isRunning2) {
}
}
public void proces(int index) {
try {
synchronized (locks[index]) {
System.out.println("Synchronized Block Begin");
socketProces();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
System.out.println("Run begin");
while (isRunning) {
proces(1);
}
Thread.sleep(1);
} catch (InterruptedException e) {
//Do Something
} catch (Exception e) {
e.printStackTrace();
}
}
}
Result:
Run begin
Synchronized Block Begin
Run begin
When you start the synchronizedBlock thread you'll get a stack trace like this I think:
run -> proces -> socketProcess.
Then because isRunning2 = true, the thread will enter an infinite loop in socketProcess and never terminate.
Keep in mind that in Java there is no such thing as 'restarting' a thread. Once started, a thread can never be restarted. Indeed, you are creating two sycnchronizedBlock objects, not restarting a single object.
As a side note, it is generally problematic to overwrite static state in a class constructor, as you're doing with the locks variable, without synchronization.
The issue here is the Integer cache which is used in the for loop to initialize the synchronizedBlock.locks array:
for (Integer i = 0; i < 5; i++) {
synchronizedBlock.locks[i] = i;
}
When this code is run again, due to the constructor of the second synchronizedBlock, the synchronizedBlock.locks array contains the same Integer instances which where created when this for loop was executed for the first time. This means that the synchronized (locks[index]) lock will be on the same Integer object. As you have already one thread holding the lock for the Integer(1) object, the second thread waits outside the lock waiting for it to be released.
This is also problematic in combination with the fact that the first thread is not terminating. Your method
public void socketProces() {
while (isRunning2) {
}
}
is an endless loop as you don't change the value of isRunning2, ever. Also, the interrupt() method itself does not stop any thread. Instead, it sets just an internal flag in the Thread class, which can be checked with isInterrupted() and interrupted(). You have to check this flag and react on it like "Oh, someone wants me to stop, so I stop now".
To solve your problem you should at least quit your thread when the "isInterrupted" flag of the Thread instance is set. You can do it like this:
public void socketProces() {
while (isRunning2) {
if (Thread.interrupted()) {
return;
}
}
}
Instead of returning from socketProces() normally you could throw an InterruptedException like other methods do.
Also, depending on how you want to initialize/use the instances you want to lock on with synchronized(...), you might want to consider on how you create/fill the synchronizedBlock.locks array and which objects you want to use (the Integer cache might be problematic here). It depends on you if the creation of a new synchronizedBlock instance will/should/shouldn't create new objects to lock on in the synchronizedBlock.locks array.

Interrupting unknown thread

Consider the following (simplified) class, designed to allow my entire component to enter some interim state before completely stopping. (The purpose of the interim state is to allow the component to complete its existing tasks, but reject any new ones).
The component might be started and stopped multiple times from any number of threads.
class StopHandler {
boolean isStarted = false;
synchronized void start() {isStarted = true;}
//synchronized as I do want the client code to block until the component is stopped.
//I might add some async method as well, but let's concentrate on the sync version only.
synchronized void stop(boolean isUrgent) {
if (isStarted) {
if (!isUrgent) {
setGlobalState(PREPARING_TO_STOP); //assume it is implemented
try {Thread.sleep(10_000L);} catch (InterruptedException ignored) {}
}
isStarted = false;
}
}
The problem with the current implementation is that if some client code needs to urgently stop the component while it is in the interim state, it will still have to wait.
For example:
//one thread
stopHandler.stop(false); //not urgent => it is sleeping
//another thread, after 1 millisecond:
stopHandler.stop(true); //it's urgent, "please stop now", but it will wait for 10 seconds
How would you implement it?
I might need to interrupt the sleeping thread, but I don't have the sleeping thread object on which to call 'interrupt()'.
How about storing a reference to current Thread (returned by Thread.currentThread()) in a field of StopHandler directly before you call sleep? That would allow you you to interrupt it in the subsequent urgent call in case the Thread is still alive.
Couldn't find a better solution than the one suggested by Lars.
Just need to encapsulate the sleep management for completeness.
class SleepHandler {
private final ReentrantLock sleepingThreadLock;
private volatile Thread sleepingThread;
SleepHandler() {
sleepingThreadLock = new ReentrantLock();
}
void sleep(long millis) throws InterruptedException {
setSleepingThread(Thread.currentThread());
Thread.sleep(millis);
setSleepingThread(null);
}
void interruptIfSleeping() {
doWithinSleepingThreadLock(() -> {
if (sleepingThread != null) {
sleepingThread.interrupt();
}
});
}
private void setSleepingThread(#Nullable Thread sleepingThread) {
doWithinSleepingThreadLock(() -> this.sleepingThread = sleepingThread);
}
private void doWithinSleepingThreadLock(Runnable runnable) {
sleepingThreadLock.lock();
try {
runnable.run();
} finally {
sleepingThreadLock.unlock();
}
}
}
With this helper class, handling of the original problem is trivial:
void stop(boolean isUrgent) throws InterruptedException {
if (isUrgent) {sleepHandler.interruptIfSleeping();} //harmless if not sleeping
try {
doStop(isUrgent); //all the stuff in the original 'stop(...)' method
} catch (InteruptedException ignored) {
} finally {
Thread.interrupted(); //just in case, clearing the 'interrupt' flag as no need to propagate it futher
}

How to wait for threads to complete in Java where threads are initiated using run()

I am starting these threads:
ThreadingHDFSUsage HDFSUsage=new ThreadingHDFSUsage(dcaps);
ThreadingRAMandContainers RAMandContainers=new ThreadingRAMandContainers(dcaps);
ThreadingCoreNodesHDFSUsage CoreNodesHDFSUsage=new ThreadingCoreNodesHDFSUsage(dcaps);
ThreadingApplicationMonitoring ApplicationMonitoring= new ThreadingApplicationMonitoring(dcaps);
How should i wait for all these threads to complete before doing some other operation.
My sample thread class code for one thread operation is:
public class ThreadingHDFSUsage extends Thread {
//private PhantomJSDriver driver;
private DesiredCapabilities dcaps;
public ThreadingHDFSUsage(DesiredCapabilities dcaps) {
// TODO Auto-generated constructor stub
this.dcaps = dcaps;
}
public void run(){
System.out.println("task HDFS Usage");
PhantomJSDriver driver = new PhantomJSDriver(dcaps);
try {
Thread.sleep(10000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(".........HDFS Usage..........");
String OverallHDFSUsage[] = null;
try {
OverallHDFSUsage = HDFSUsage.getWebData(driver,"http://1.2.3.4:8888/dfshealth.html#tab-overview","//*[#id=\"tab-overview\"]/table[2]/tbody/tr[2]/td","");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String OverallHDFSUsage1 = OverallHDFSUsage[0];
}
}
Similarly, I have relevant code for other threads.
So, how do i wait for all these 4 thread operation to complete?
Just join() them again:
HDFSUsage.join();
RAMandContainers.join();
CoreNodesHDFSUsage.join();
ApplicationMonitoring.join();
Each join() waits for the specific thread to finish.
There's also CompletionService in JDK concurrent package. To use it, you switch from explicit Threads to tasks, represented as instances of Callable<ResultType> or Runnable. While code may look slightly more complicated, it is quite convenient, once you became used to it:
import java.util.concurrent.*;
class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletionService<String> completionService = new ExecutorCompletionService<>(Executors.newCachedThreadPool());
completionService.submit(() -> {
Thread.sleep(5000);
return "sleeped for 5000 millis";
});
completionService.submit(() -> {
Thread.sleep(1000);
return "sleeped for 1000 millis";
});
// etc
System.out.println("Completed: " + completionService.take().get());
System.out.println("Completed: " + completionService.take().get());
}
}
Both of the other answers are correct, but for completeness, there's yet another way to do what you want using a Semaphore. This method won't yield results different from any of the other answers, but may be faster if any of your threads have to do something expensive after the results you want are obtained, prior to returning. Inside each of your threads, call s.release() as soon as all pertinent work is finished. Your controller thread might look like this ...
Semaphore s = new Semaphore(0);
//start all four of your threads here and pass 's' to each
s.acquire(4);
... and your worker threads might look like this:
#Override
public void run(){
//compute results
s.release(1);
//do expensive cleanup and return
}

Using boolean var for stopping threads

I have a Java book I'm learning from and in one of the examples, I saw something suspicious.
public class ThreadExample extends MIDlet {
boolean threadsRunning = true; // Flag stopping the threads
ThreadTest thr1;
ThreadTest thr2;
private class ThreadTest extends Thread {
int loops;
public ThreadTest(int waitingTime) {
loops = waitTime;
}
public void run() {
for (int i = 1; i <= loops; i++) {
if (threadsRunning != true) { // here threadsRunning is tested
return;
}
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.println(e);
}
}
}
}
public ThreadExample() {
thr1 = new ThreadTest(2);
thr2 = new ThreadTest(6);
}
public void startApp() throws MIDletStateChangeException {
thr1.start();
thr2.start();
try {
Thread.sleep(4000); // we wait 4 secs before stopping the threads -
// this way one of the threads is supposed to finish by itself
} catch(InterruptedException e) {
System.out.println(e);
}
destroyApp();
}
public void destroyApp() {
threadsRunning = false;
try {
thr1.join();
thr2.join();
} catch(InterruptedException e) {
System.out.println(e);
}
notifyDestroyed();
}
}
As it is a MIDlet app, when it's started, the startApp method is executed. To keep it simple, the startApp method itself calls destroyApp and so the program destroys, stopping the threads and notifying the destruction.
The question is, is it safe to use this 'threadsRunning' variable and would its use inside both threads and in the destroyApp method cause any trouble at some point? Would 'volatile' keyword put in front of the declaration help to synchronize it?
Setting a boolean value is atomic, and there is no "read then modify" logic in this example, so access to the variable doesn't need to be synchronised in this particular case.
However, the variable should at least be marked volatile.
Marking the variable volatile does not synchronise the threads' access to it; it makes sure that a thread doesn't miss another thread's update to the variable due to code optimisation or value caching. For example, without volatile, the code inside run() may read the threadsRunning value just once at the beginning, cache the value, and then use this cached value in the if statement every time, rather than reading the variable again from main memory. If the threadsRunning value gets changed by another thread, it might not get picked up.
In general, if you use a variable from multiple threads, and its access is not synchronised, you should mark it volatile.

Why does java thread wait() work only with time limit in here?

I am trying to get familiar with Java threads for the SCJP and I had a question.
In the below-written code i simply created:
two Runnables with
a common data storage (an array) and
a synchronized write() method to fill it with data successively leaving a letter as a mark for each Runnable (A and B) in sequence.
I know the code is rough and could be better written but I was seeking the moral of the threads.
So now when I run it, it never terminates and the results stop at:
Still good.
A0.
But when I change wait() to wait(100) it works just fine counting from 0 to 9 and it terminates normally. Could someone explain the reason behind that for me please?
Thank you.
public class ArrayThreads {
Object[] array = new Object[10];
boolean isA = true;
int position = 0;
int getIndex(){
return position;
}
class ThreadA implements Runnable{
synchronized void write(String value){
while(!isA){
try {
wait();
} catch (InterruptedException ex) {
System.out.println("An error in" + value);
ex.printStackTrace();
}
}
array[position] = value + position;
System.out.println(array[position]);
position++;
isA = !isA;
notify();
}
public void run() {
while(getIndex()<array.length){
if (getIndex()==9) return;
else
write("A");}
}
}
class ThreadB implements Runnable{
synchronized void write(String value){
while(isA){
try {
wait();
} catch (InterruptedException ex) {
System.out.println("An error in" + value);
ex.printStackTrace();
}
}
array[position] = value + position;
System.out.println(array[position]);
position++;
isA = !isA;
notify();
}
public void run() {
while(getIndex()<array.length){
if (getIndex()==9) return;
else
write("B");}
}
}
public static void main(String[] args){
ArrayThreads threads = new ArrayThreads();
Thread threadA = new Thread(threads.new ThreadA());
Thread threadB = new Thread(threads.new ThreadB());
System.out.println("Still good");
threadB.start();
threadA.start();
}
}
Your threads are each waiting and notifying separate objects - so they're not communicating with each other at all. If you want them to effectively release each other, they'll need a shared monitor to synchronize, wait on and notify.
It's "working" when you specify a timeout because it's effectively turning the wait call into a sleep call... still nothing is really waiting/notifying usefully, because the two threads are still dealing with separate monitors.
your objects are not working in same monitor.
you need to either move the wait() and notify() to same object like:
http://www.java-samples.com/showtutorial.php?tutorialid=306
or you can notify the target object:
http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ315_016.htm
when you set wait(100). you are setting a timeout. and definitely it will wake up after 100ms.

Categories

Resources