I have a code and I want to ensure the order in which the robot's legs move using wait() and notify(). Here is the code:
public class Leg implements Runnable {
private final Object monitor = new Object();
private final String name;
public Leg(String name) {
this.name = name;
}
#Override
public void run() {
while (true) {
synchronized (monitor) {
move();
monitor.notify();
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void move() {
System.out.println(name);
}
public static void main(String[] args) {
CompletableFuture.allOf(
CompletableFuture.runAsync(new Leg("left")),
CompletableFuture.runAsync(new Leg("right"))
).join();
}
}
Right now the output is the below:
left
right
// and then it stops moving.
I want the code continue moving (not only once). That's why it's interesting for me what am I doing wrong?
You have 2 Leg object with 2 threads to process, for each thread you have a monitor object, so when you use notify and wait, it just effects to one thread (which thread is running currently):
synchronized (monitor) {
move();
monitor.notify(); // notify current thread, it's no meaning
try {
monitor.wait(); // current thread will block here and there is no thread wake up it
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Maybe it's what you need:
import java.util.concurrent.CompletableFuture;
public class Leg implements Runnable {
private final String name;
private Leg nextLeg;
private volatile boolean active;
public Leg(String name) {
this.name = name;
}
public void setNextLeg(Leg nextLeg) {
this.nextLeg = nextLeg;
}
public void active() {
synchronized (this) {
this.active = true;
notify();
}
}
#Override
public void run() {
while (true) {
try {
synchronized (this) {
while (!active) {
wait();
}
move();
active = false;
nextLeg.active();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
private void move() {
System.out.println(name);
}
public static void main(String[] args) {
Leg left = new Leg("left");
Leg right = new Leg("right");
left.setNextLeg(right);
right.setNextLeg(left);
left.active();
CompletableFuture.allOf(
CompletableFuture.runAsync(left),
CompletableFuture.runAsync(right)
).join();
}
}
Related
I am trying to create a synchronized version of data and using junit to test my method. The code below is what I came so far. It works quite well if I put on the main method (the counter is increased one by one by each thread) but the test process will stop immediately. Is this the problem by using Thread.sleep() on a test case?
public void testGeneral() {
class SynchronizedData {
public AtomicBoolean lock = new AtomicBoolean(false);
public int counter = 0;
public void update() {
if(lock.compareAndSet(false, true)) {
counter++;
System.out.println(counter);
lock.set(false);
}
}
}
SynchronizedData data = new SynchronizedData();
class Handler implements Runnable {
String name;
public Handler(String name) {
this.name = name;
}
#Override
public void run() {
for(;;) {
try {
Thread.sleep(new Random().nextInt(100));
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(this.name);
data.update();
}
}
}
new Thread(new Handler("One")).start();
new Thread(new Handler("Two")).start();
}
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 am new to java thread. I am unable to give the lock back to the thread from the main thread in the following code. I am getting the undesired output because i am unable to unlock the thread. I want thread to increment the value using thread (goes to wait state after that) and after printing the value, release the lock to print the next incremented value.
class Foo implements Runnable
{
public volatile int value=0,i=0;
Thread t=new Thread();
public void method(Thread t)
{
this.t = t;
}
#Override
public synchronized void run()
{
while(i<3)
{
value++;//receive and process ACK
i++;
try
{
System.out.println("im thread here");
wait();
System.out.println("passed wait");
}
catch(InterruptedException ex){
}
System.out.println("im notified");
}//while
//}//sync
}//run method
public int getValue()
{
try
{
Thread.sleep(1000);
}
catch (Exception e) {
System.out.println(e);
}
return value;
}
}//class foo
public class ThreadTest
{
public static int value1,times=0;
public static void main(String[] args)
{
Foo foo=new Foo();
Thread t=new Thread(foo);
foo.method(t);
t.start();
while(times<3)
{
synchronized(t)
{
value1=foo.getValue();
times++;
System.out.println(value1);
System.out.println(t.getState());
try
{
t.notify();
System.out.println("Notify is reached");
}
catch(IllegalMonitorStateException ex)
{
System.out.println("Thread is blocked");
}
}//sync
}//while
}//main
}//mclasss
Are you trying to do something like this? If you really must use wait/notify & want to use Runnable.
I added a wait block, otherwise the main thread may finish before the background thread increments the value.
class Foo implements Runnable {
public volatile int value = 0, i = 0;
private Thread backgroundThread;
public void setThread(Thread thread) {
this.backgroundThread = thread;
}
#Override
public void run() {
synchronized (backgroundThread) {
while (i < 2) {
value++;
i++;
backgroundThread.notify();
try {
System.out.println("background thread wait start");
backgroundThread.wait();
System.out.println("background thread notified");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
public int getValue() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
}
public class ThreadTest {
public static int value1, times = 0;
public static void main(String[] args) {
Foo foo = new Foo();
final Thread thread = new Thread(foo);
foo.setThread(thread);
thread.start();
while (times < 3) {
synchronized (thread) {
value1 = foo.getValue();
times++;
System.out.println(value1);
System.out.println(thread.getState());
thread.notify();
try {
thread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Or you can extend thread:
class BackgroundThread extends Thread {
public volatile int value = 0, i = 0;
#Override
public synchronized void run() {
while (i < 2) {
value++;
i++;
notify();
try {
System.out.println("background thread wait start");
wait();
System.out.println("background thread notified");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
public int getValue() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
}
public class ThreadTest {
public static int value1, times = 0;
public static void main(String[] args) {
BackgroundThread backgroundThread = new BackgroundThread();
backgroundThread.start();
while (times < 3) {
synchronized (backgroundThread) {
value1 = backgroundThread.getValue();
times++;
System.out.println(value1);
System.out.println(backgroundThread.getState());
backgroundThread.notify();
try {
backgroundThread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
It is very unclear what you really want to do but we will assume here that you want to run a thread in the background which should run only when its spawner (let's say the main thread) allows it to.
The JDK has several tools for this already, no need to rely on the low level wait() and notify{,All}() methods.
One example of such a primitive is a CountDownLatch. It is a one-use entity which allows you to specify the times a given set of threads should countDown() it before any threads .await()ing for them can trigger.
In combination with the multithread handling classes which appeared as far back as Java 1.5, this means you could do something like this:
// Implementation of a Runnable waiting for the counter to trigger
public final class MyWaitingClass
implements Runnable
{
private final CountDownLatch latch;
public MyWaitingClass(final CountDownLatch latch)
{
this.latch = latch;
}
#Override
public void run()
{
try {
latch.await();
// do whatever is necessary
} catch (InterruptedException e) {
// Argh; interrupted before the latch was released
Thread.currentThread().interrupt();
}
}
}
// In the main class:
final ExecutorService executor = Executors.newSingleThreadPool();
final CountDownLatch latch = new CountDownLatch(1);
final Runnable runnable = new MyWaitingClass(latch);
executor.submit(runnable);
// do whatever is needed; then:
latch.countDown();
I'm working on a variant of the producer consumer problem in Java. I have a producer thread creating objects, that are put into an priority blocking queue, and then passed into the main container, the controller, which is a bounded buffer.
The reason for the queue is that when the main container has a certain % of Object A, it will only accept objects of type B, and some other scenarios that we have been asked to look at.
I'm having trouble figuring out what is going wrong with the code, the debugger is just jumping from in.offer in InQueue, and in.push in Producer. Any direction or advice would be appreciated.
import java.util.concurrent.PriorityBlockingQueue;
public class InQueue implements Runnable {
Controller c;
private PriorityBlockingQueue in;
public InQueue(Controller c) {
this.c = c;
in = new PriorityBlockingQueue();
}
public void push(C c) {
in.offer(c);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
while (true) {
try {
C temp = (C) in.take(); //will block if empty
c.arrive(temp);
} catch (InterruptedException e) {} // TODO
}
}
}
public class Controller {
private BoundedBuffer buffer;
private int used;
Controller(int capacity) {
this.buffer = new BoundedBuffer(capacity);
used = 0;
}
public void arrive(C c) {
try {
buffer.put(c);
used++;
} catch (InterruptedException e) { } //TODO
}
public C depart() {
C temp = null; //BAD IDEA?
try {
temp = (C)buffer.take();
used--;
} catch (InterruptedException e) { } //TODO
return temp; //could be null
}
}
Your code is not compiling because of the wrong way your using generics. Another thing is that there is no default implementation of BoundedBuffer. Below I made a working implementation for the producer - consumer problem below with blocking queues. Have a look and correct your mistakes.
package concurrency;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class Producer<T> {
private final BlockingQueue<T> queue;
private final Consumer consumer;
private static volatile boolean isShutdown;
private final static Object lock = new Object();
public Producer() {
this.queue = new LinkedBlockingQueue<T>();
this.consumer = new Consumer();
}
public void start() {
consumer.start();
}
public void stop() {
synchronized (lock) {
isShutdown = true;
}
consumer.interrupt();
}
public void put(T obj) throws InterruptedException {
synchronized (lock) {
if (isShutdown)
throw new IllegalStateException("Consumer Thread is not active");
}
queue.put(obj);
}
private class Consumer extends Thread {
public void run() {
while (true) {
synchronized (lock) {
if (isShutdown)
break;
}
T t = takeItem();
// do something with 't'
if(t!=null)
printItem(t);
}
}
private void printItem(T t) {
System.out.println(t);
}
private T takeItem() {
try {
return queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return null;
}
}
public static void main(String[] args) throws InterruptedException {
Producer<Integer> producer = new Producer<Integer>();
producer.start();
for (int i = 0; i <20; i++) {
producer.put(i);
if (i >= 7)
Thread.sleep(500);
}
producer.stop();
}
}
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();