how to make notify() works properly with wait() - java

I am trying to make a program simulating a very simple dishwasher which has three threads. The first thread is responsible for adding water, the second thread for opening the door of the device which should force the adding water thread to wait until the third thread notify(). the system runs but it never stops and the notify() never works.
import java.util.logging.Level;
import java.util.logging.Logger;
public class threadexample {
public static boolean flag = false;
void Open() throws InterruptedException {
synchronized (threadexample.this) {
flag = true;
Thread.sleep(2000);
System.out.println("producer thread paused");
wait();
System.out.println("Resumed");
}
}
void Close() throws InterruptedException {
synchronized (threadexample.this) {
flag = false;
Thread.sleep(6000);
System.out.println("System resuming..");
notifyAll();
Thread.sleep(2000);
}
}
public static void main(String[] args) throws InterruptedException {
threadexample closing = new threadexample();
threadexample openning = new threadexample();
final Door door = new Door();
// Create a thread object that calls pc.produce()
Thread t3 = new Thread(new Runnable() {
#Override
public void run() {
if (flag == false) {
for (int check = 0; check <= 8; check++) {
if (check == 1) {
System.out.println("Adding Water..." + Thread.currentThread().getName());
} else {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
if (flag == true) {
try {
closing.Close();
} catch (InterruptedException ex1) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex1);
}
}
}
}
}
}
try {
Thread.sleep(4000);
} catch (InterruptedException ex) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
openning.Open();
} catch (InterruptedException ex) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
closing.Close();
} catch (InterruptedException ex) {
Logger.getLogger(threadexample.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
t1.start();
t2.start();
t3.start();
}
}

1) You call wait without checking whether or not the thing you are waiting for has already happened. If you wait for something that has already happened, you will wait forever because notify will not be called again.
2) You call sleep while holding the lock. That doesn't make sense.
3) You have:
threadexample closing = new threadexample();
threadexample openning = new threadexample();
and:
synchronized(threadexample.this)
So you create two instances of threadexample and each thread synchronizes on its own instance of threadexample. That's not right either.

You never actually call openning.Close(), hence openning.notify() is never called. Therefore, Thread t1 waits forever. Mind you, wait() and notify() call the Object's monitor and are not static. You want to use threadexample lock = new threadExample().

Related

Thread won't enter synchronized block

I have a Button in my android app which must run a continuous action while holding it down, for that I created an onTouchListener to handle such issue, my structure is when catching ACTION_DOWN event a thread with a while(true) loop runs, then when catching ACTION_UP event that thread stopped via wait() in order to resume it's looping again upon holding down, the problem is that when trying to execute thread.wait() the thread doesn't enter the synchronized block and doesn't wait, but it stops the execution of runOnUIThread which exists in that thread, and after I press any button after that the app crashes and gives me ANR Exception : Input dispatching timed out:
// the thread declaratrion
test = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
// still loops here
value = value + 1;
runOnUiThread(new Runnable() {
public void run() {
// doesn't go here anymore
mTextView.setText(Integer.toString(value));
}
});
// still loops here
synchronized (test) {
try {
Thread.sleep(150);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
// the onTouchListener
case MotionEvent.ACTION_DOWN:
if (!test.isAlive()) {
synchronized (test) {
test.start();
}
} else {
synchronized (test) {
test.notify();
}
}
break;
case MotionEvent.ACTION_UP:
// accepts the action
synchronized (test) {
try {
// doesn't goes here
test.wait(); // doesn't execute
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
default:
break;
Probably you use too low level API for your needs. Just look at http://developer.android.com/reference/java/util/concurrent/ScheduledExecutorService.html
One thing I see is potential dangerous is that in your separate thread, you are waiting inside a synchronized statement. So when that guy is sleeping, it takes the lock with him, and therefore in your onTouchListener, none could grabbed the lock but to wait. And because the onTouchListener is controlled in the framework, it may stop running if it waits too long. I did a simple test here to prove it.
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
final Object globalLock = new Object();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (globalLock) {
System.out.println("thread1 grabbed the lock.");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1 returned the lock.");
}
}
});
t1.start();
Thread.sleep(200);
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("thread2 is waiting for the lock...");
synchronized (globalLock) {
System.out.println("thread2 got the lock");
}
}
});
t2.start();
t1.join();
t2.join();
}
}

Java - Synchronize Threads on certain point

I need to synchronize some threads at a certain checkpoint, and only after all threads have reached this point, they should continue. Is there any easy construct?
for (int v = 0; v < 10; v++) {
new Thread(new Runnable() {
#Override
public void run() {
try {
doFirst();
//checkpoint
doSecond();
} catch (Throwable e) {
e.printStackTrace();
}
}
}).start();
}
import java.util.concurrent.CountDownLatch;
private CountDownLatch countDownLatch = new CountDownLatch(10)
...
public void run() {
doFirst();
countDownLatch.countDown();
countDownLatch.await();
doSecond();
}
---- OR (1 less line of code) ----
import java.util.concurrent.CyclicBarrier;
private CyclicBarrier cyclicBarrier= new CyclicBarrier(10)
...
public void run() {
doFirst();
cyclicBarrier.await();
doSecond();
}
If you know the exact number of your threads you can use CountDownLatch from java.util.concurrent.
// First initialize latch with your number of threads
CountDownLatch latch = new CountDownLatch(N);
// Then give this instance of latch to each of your threads
// and finally at your checkpoint do
latch.countDown();
latch.await();
That's all.
You can do this using a lock object:
Integer threadCount = 10;
for (int i = 0; i < threadCount; i++)
{
new Thread(() ->
{
try
{
doFirst();
synchronized (threadCount)
{
threadCount--;
while (threadCount > 0)
threadCount.wait();
threadCount.notifyAll();
}
doSecond();
}
catch (Exception e) { e.printStackTrace(); }
}).start();
}
// all threads are started, to wait until they've finished, call threadCount.wait();
One way to do it is to synchronize your threads over a common monitor:
Object monitor = new Object();
int jobCount = 0;
public void f1(){
for (int v = 0; v < 10; v++) {
new Thread(new Runnable() {
#Override
public void run() {
try {
doFirst();
check();
doSecond();
} catch (Throwable e) {
e.printStackTrace();
}
}
}).start();
}
}
public void sleep(){}
public void check(){
synchronized(monitor){
jobCount++;
if(jobCount==10){
monitor.notifyAll();
return;
}
}
monitor.wait();
}
Things to consider:
When you call monitor.wait(), the thread where that invocation was made will go to sleep, synchronized over monitor
notifyAll() will awaken all threads that are sleeping and synch. over its recipient.
When one thread enters a synchronized block, it will take a lock over monitor. notifyAll() can only be invoked if a lock exists on its recipient

java: Printing odd even numbers using 2 threads

I am trying to print odd and even numbers using 2 different threads alternately. I was able to achieve it using wait, notify and synchronize block but now i want to evaluate if we can achieve it without using wait, notify and synchronize.
Following is the code i have but its not working:
public class OddEvenUsingAtomic {
AtomicInteger nm = new AtomicInteger(0);
AtomicBoolean chk = new AtomicBoolean(true);
public static void main(String args[]) {
final OddEvenUsingAtomic pc = new OddEvenUsingAtomic();
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (pc.chk.compareAndSet(true, false)) {
System.out.println("Odd: " + pc.nm.incrementAndGet());
}
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
if (pc.chk.compareAndSet(false, true)) {
System.out.println("Even: " + pc.nm.incrementAndGet());
}
}
}
}).start();
}
}
Any ideas?
I created another version after suggestions from Bruno which seems to be working better:
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class OddEvenUsingAtomic {
AtomicInteger nm = new AtomicInteger(0);
AtomicBoolean chk = new AtomicBoolean(true);
public static void main(String args[]) {
final OddEvenUsingAtomic pc = new OddEvenUsingAtomic();
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (pc.chk.get() == Boolean.TRUE) {
System.out.println("Odd: " + pc.nm.incrementAndGet());
pc.chk.compareAndSet(true, false);
}
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
if (pc.chk.get() == Boolean.FALSE) {
System.out.println("Even: " + pc.nm.incrementAndGet());
pc.chk.compareAndSet(false, true);
}
}
}
}).start();
}
}
The code is not correctly synchronized, that's the problem.
The following execution order is allowed in your code:
First thread sees chk == true, sets it to false and enters the if block.
Second thread sees chk == false, sets it to true and enters the if block.
Now, you have 2 threads both inside their if blocks, getting ready to:
incrementAndGet() the number
Print it.
Therefore, you have absolutely no control on what is going to happen.
You can have any of the threads call incrementAndGet(), therefore you can have thread "Odd" printing, first, an odd number, and later, an even number.
You can have the first thread print the number, loop, see that the condition is satisfied again (since the second thread has set chk to true again, print, all of this before the second thread had the chance to print).
As you can see, to achieve the result you want, you must have the following operations done atomically:
compareAndSet() the boolean
incrementAndGet() the number
print it
If the 3 operations are not atomic, then you can have the threads being scheduled to run the operations in any possible order, you have no control on the output. The easiest way to achieve this is to use a synchronized block:
public static void main(final String... args) {
final Object o = new Object();
// ... thread 1 ...
synchronized(o) {
if (boolean is in the expected state) { change boolean, get number, increment, print }
}
// ... thread 2 ...
synchronized(o) {
if (boolean is in the expected state) { change boolean, get number, increment, print }
}
}
Here are two threads printing odds and evens with no wait, notify, or synchronized (at least not in the code you can see):
import java.util.concurrent.*;
public class ThreadSignaling {
public static void main(String[] args) {
BlockingQueue<Integer> evens = new LinkedBlockingQueue<>();
BlockingQueue<Integer> odds = new LinkedBlockingQueue<>();
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(() -> takeAndOfferNext(evens, odds));
executorService.submit(() -> takeAndOfferNext(odds, evens));
evens.offer(0);
}
private static void takeAndOfferNext(BlockingQueue<Integer> takeFrom,
BlockingQueue<Integer> offerTo) {
while (true) {
try {
int i = takeFrom.take();
System.out.println(i);
offerTo.offer(i + 1);
} catch (InterruptedException e) {
throw new IllegalStateException("Unexpected interrupt", e);
}
}
}
}
class MultiThreading {
Integer counter = 0;
Thread even;
Thread odd;
boolean flagEven = true;
boolean flagOdd;
class ThreadEven implements Runnable {
#Override
public void run() {
try {
while (counter < 100) {
if (flagEven) {
System.out.println(counter);
counter++;
flagEven = false;
flagOdd = true;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ThreadOdd implements Runnable {
#Override
public void run() {
try {
synchronized (even) {
while (counter < 100) {
if (flagOdd) {
System.out.println(counter);
counter++;
flagOdd = false;
flagEven = true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void start() {
even = new Thread(new ThreadEven());
odd = new Thread(new ThreadOdd());
even.start();
odd.start();
}
}
}
call in the main method
new MultiThreading().start();

I can't finish thread (runnable), how it is?

Thread thread;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_yippi);
final Handler hn=new Handler();
final TextView text=(TextView)findViewById(R.id.TextView01);
final Runnable r = new Runnable()
{
public void run()
{
text.settext("hi");
}
};
thread = new Thread()
{
#Override
public void run() {
try {
while(true) {
sleep(1750);
hn.post(r);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
thread.stop();}
The code here. I can not stop the runnable thread. Also, thread.stop() and thread.destroy() are deprecated. Can somebody help me? And also I don't understand how to stop the thread with the thread.interrupt() method. What's wrong?
The JavaDoc for Thread.stop() lists the following article as explanation for why stop() is deprecated: http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
Most 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. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized).
interrupt() is more suitable to stop some Thread from waiting for something, that is probably not coming anymore. If you want to end the thread, it's best to let its run() method return.
Create a boolean variable to stop the thread and use it in while(boolean) instead of while(true).
You can use Thread.interrupt() to trigger the InterruptedException within your thread. I've added code below that demonstrates the behavior. The mainThread is where your code would be and the timer Thread is just used to demonstrate delayed triggering of the interrupt.
public class Test {
public static void main(String[] args) {
final Thread mainThread = new Thread() {
#Override
public void run() {
boolean continueExecution = true;
while (continueExecution) {
try {
sleep(100);
System.out.println("Executing");
} catch (InterruptedException e) {
continueExecution = false;
}
}
}
};
mainThread.start();
Thread timer = new Thread() {
#Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Stopping recurring execution");
mainThread.interrupt();
}
};
timer.start();
}
}
You can use interrupt method of Thread to try stop a thread, like below code.
May be it`s useful to you.
public class InterruptThread {
public static void main(String args[]){
Thread thread = new Thread()
{
#Override
public void run() {
try {
while(true) {
System.out.println("Thread is Runing......");
sleep(1000);
}
} catch (InterruptedException e) {
// restore interrupted status
System.out.println("Thread is interrupting");
Thread.currentThread().interrupt();
}
}
};
thread.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Will Interrupt thread");
thread.interrupt();
}
}

how to terminate thread sendMsgToServer when exit is sent from the server side

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.atomic.AtomicBoolean;
public class ThreadSandbox {
//static volatile boolean runLoopX = true;
static AtomicBoolean runLoopX = new AtomicBoolean();
public static void main(String[] args) {
final Thread thread1 = new Thread(new Runnable(){
#Override
public void run()
{
try {
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
String userInputStr = "";
do {
System.out.println("Enter text for thread 1:");
userInputStr = userInput.readLine().trim();
System.out.println("User Input for thread 1: " + userInputStr);
} while (userInputStr.equals("e") == false && runLoopX.get()== false);
} catch (Exception e) {System.err.println(e.toString());}
runLoopX.set(true);
}
});
final Thread thread2 = new Thread(new Runnable(){
#Override
public void run()
{
try {
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
String userInputStr = "";
do {
System.out.println("Enter text for thread 2:");
userInputStr = userInput.readLine().trim();
System.out.println("User Input for thread 2: " + userInputStr);
} while (userInputStr.equals("e") == false && runLoopX.get()== false);
} catch (Exception e) {System.err.println(e.toString());}
runLoopX.set(true);
}
});
Thread thread3 = new Thread(new Runnable(){
#Override
public void run()
{
do {
if (runLoopX.get() == true) {
thread1.interrupt();
thread2.interrupt();
}
} while (runLoopX.get() == false);
}
});
thread1.start();
thread2.start();
thread3.start();
try {
thread1.join();
thread2.join();
thread3.join();
} catch (Exception e) {System.err.println(e.toString());}
}
}
Issue:
If I enter "e" for thread1 input then thread1 terminates but thread2 is still running and If I enter "e" for thread2 input then thread2 terminates but thread1 is still running.
How do I terminate both threads when "e" is entered in either threads?
you should synchronize your threads for the inputs.
but a synchronized String and made all of your threads check this string before trying to read anything
so if this string has the value "e" then the thread will terminate it self. if not just read the input but the value in the string and continue.
make sure about this String be synchronized and I would like to make it volatile
to more specific this is a bad example of threads ! if one thread will lock the application until the user enters some data. the other thread should wait in the wait queue for more performance.
in this case all of your threads will be kept in the ready queue and this will consume the CPU utilization.
to solve this problem try to use Lock and Conditions.
this is a fast pesedo-code to solve the problem on sockets :
public class ThreadSandbox {
public static syncrnized boolean continueWork = true;
public static void main(String[] args) {
final Thread thread1 = new Thread(new Runnable(){
#Override
public void run()
{ while(continueWork){
try {
socket.setSoTimeout(5 *1000);
//READ str FROM SOCKET
if(str.equals("e")) {
continueWork =false;
}
} catch (TimeoutException e) {
System.err.println(e.toString());
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
});
final Thread thread2 = new Thread(new Runnable(){
#Override
public void run()
{ while(continueWork){
try {
socket.setSoTimeout(5 *1000);
//READ str FROM SOCKET
if(str.equals("e")) {
continueWork =false;
}
} catch (TimeoutException e) {
System.err.println(e.toString());
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
});
thread1.start();
thread2.start();
}
}

Categories