Code snippet:
class Counter implements Runnable {
Object s = new Object();
#Override
public void run() {
try {
synchronized (s) {
s.wait(10000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
//...do Something
}
public void stopCounter() {
synchronized (s) {
s.notifyAll();
}
}
}
Irrespective of whether i call stopCounter or not, the ...do Something code always executes only after the wait interval. Even after notify it still waits for 10 secs.
I cannot tell from your example what you are trying to achieve. If it is to try and replace some sort of polling then consider the BlockingQueue interface that was released in Java 5. Since that has appeared I have had no need for wait/notify. It's a lot more simple to use and java behind the scenes does the equivalent of the wait/notify for you.
It depends of the way you use it. I have just tried it by adding a main method and running it and it seems like the wait / notify mechanism is working fine, not the way you described it. Please try it yourself:
public static void main(String[] args) {
Counter c = new Counter();
new Thread(c).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
c.stopCounter();
}
My guess is that you call the run and stopCounter methods on different instances of your Counter class. They therefore use different monitors (your s = new Object()) and the call to stop won't notify the other Counter.
For example, this would behave similarly to what you describe (unless you get a spurious wakeup):
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
new Thread(c).start();
Thread.sleep(200);
new Counter().stopCounter();
}
static class Counter implements Runnable {
Object s = new Object();
#Override
public void run() {
try {
System.out.println("in");
synchronized (s) {
s.wait(10000);
}
System.out.println("out");
} catch (InterruptedException e) {
e.printStackTrace();
}
//...do Something
}
public void stopCounter() {
synchronized (s) {
s.notifyAll();
}
System.out.println("notified");
}
}
Related
I cannot find The Problem Can Someone Help me.
public class Achterbahn {
private final Object monitor = new Object();
public synchronized void test() throws InterruptedException {
//monitor.wait();
System.out.println("car");
wait();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
Thread.sleep(2000);
System.out.println("p");
notify();
//b.t1.notify();
}
public static void main(String []args) throws InterruptedException {
Thread t4 = new Thread(new Runnable() {
#Override
public void run() {
Achterbahn b = new Achterbahn();
try {
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t5= new Thread(new Runnable() {
#Override
public void run() {
Achterbahn b = new Achterbahn();
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
new Thread(t4).start();
new Thread(t5).start();
t5.join();
t4.join();
}
}
The output is:
car
p
it seems like notify is working i want print also car at the last but i donot konw why its not working
i hope Someone Help me. as soon as possible.
i have all methodes in the same class and i tried also sepreate classes but it didnt work
(I am guessing in this case that “it didn’t work” means the program hangs. Please be specific about what the issue you’re seeing is.)
There are 2 issues. One is that you are creating separate objects in each thread. The object that wait and notify are called on have to be the same, the monitor that is waited on is the one that needs to receive the notify. In this code the synchronized methods use the intrinsic lock on the instance that the methods are called on.
Create the object once in the main method, each thread needs to reference the same object.
The second issue, once you fix the first issue, will be a race condition. If the notify performed by one thread occurs first then when the wait executes the notify has already happened and the wait keeps waiting forever.
Add a condition variable to remember whether the notify occurred.
In general the pattern is to check the condition in a loop, see this question: Why we must use "while" for checking race condition not "if". The post has an example of using a variable to see if a condition occurred, here it
synchronized(obj)
{
while (condition_not_matched)
{
obj.wait();
}
//continue
dosomething();
}
You're doing several things wrong.
only start a single instance of C. Then use that instance to invoke your methods. Different instances don't share monitors within synchronized methods
You're starting two new threads when you start them. Just start them as follows:
t4.start();
t5.start();
The primary problem is that t4 starts first and immediately sleeps. So t5 won't start until the sleep finishes. But by that time, the notify() for the wait in t4 has been issued before the wait() is invoked in t5 Thus the wait will never see it. So you need to give t4 a chance to start before the sleep occurs. There are several ways to fix this. One is to use a flag to signal that the other method is ready. But do not use a tight while loop. Put a sleep inside it for a small amount of time. I have provided an example below. I also assigned names to your threads to match your variables.
public class C {
boolean ready = false;
public synchronized void test() throws InterruptedException {
System.out.println("Current thread = " + Thread.currentThread().getName());
ready = true;
System.out.println("car");
wait();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
Thread.sleep(4000);
System.out.println("Current thread = " + Thread.currentThread().getName());
System.out.println("p");
notify();
}
public static void main(String[] args)
throws InterruptedException {
C b = new C();
Thread t4 = new Thread(new Runnable() {
#Override
public void run() {
try {
while(!b.ready) {
Thread.sleep(100);
}
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"t4");
Thread t5 = new Thread(new Runnable() {
#Override
public void run() {
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"t5");
System.out.println("Starting t4");
t4.start();
System.out.println("Starting t5");
t5.start();
//
t5.join();
t4.join();
}
}
This Code work for me I have now the while loop
public class C {
int i = 34;
public synchronized void test() throws InterruptedException {
System.out.println("car");
while(i == 34) {
wait();
}
notify();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
i = 55;
System.out.println("p");
notify();
}
public static void main(String[] args)
throws InterruptedException {
C b = new C();
Thread t4 = new Thread(new Runnable() {
#Override
public void run() {
try {
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t5 = new Thread(new Runnable() {
#Override
public void run() {
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t4.start();
t5.start();
t4.join();
t5.join();
}
}
I'm looking to use a thread to process something in the background. Since this code isn't used anywhere else & is not complex I'd like to use an inline function. However the function needs a copy of an attribute at the time the thread was created i.e.: I'd like it if the output from the following example 'true' instead of 'false'
public class InlineThreadTest {
boolean value;
public static void main(String[] args) {
new InlineThreadTest();
}
InlineThreadTest() {
value = true;
java.util.concurrent.Executors.newSingleThreadExecutor().execute(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
System.out.println(value);
}
});
value = false;
}
}
... I can do what I'm looking to do by creating a separate class that implements Runnable, but having this inline seems like something that might be good.
I had a look # https://stackoverflow.com/a/362443/64696 , but cannot figure out how to mold this to my use case.
Runnable implementation is a thread and thread won't return any value. The ExecutorService.execute method just runs the thread and you have no way to get the state of the thread whether it was executed or not.
If you want to check for the task (not thread) executed by ExecutorService you should use Callable and work with sumbit(). Your modified example:
public class InlineThreadTest {
boolean value;
public static void main(String[] args) {
new InlineThreadTest();
}
InlineThreadTest() {
value = true;
java.util.concurrent.Future<Boolean> f =
java.util.concurrent.Executors.newSingleThreadExecutor().submit(new Callable<Boolean>() {
public Boolean call() {
System.out.println(value);
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
value = false;
return value;
}
});
try {
System.out.println(f.get()+" or value="+value);
} catch (Exception ex) { }
}
}
You'll get 2 lines
true
false or value=false
I was asked at an interview to write java code which is guaranteed deadlock. I wrote a standard code which presents at every Java book, like create 2 threads and call synchronized methods at different order, sleep a little before call the 2nd.
Of course this stuff didn't satisfy the interviewers, so now I'm proceeding to figure the solution out.
I discovered a piece of code:
public class Lock implements Runnable {
static {
System.out.println("Getting ready to greet the world");
try {
Thread t = new Thread(new Lock());
t.start();
t.join();
} catch (InterruptedException ex) {
System.out.println("won't see me");
}
}
public static void main(String[] args) {
System.out.println("Hello World!");
}
public void run() {
try {
Thread t = new Thread(new Lock());
t.start();
t.join();
} catch (InterruptedException ex) {
System.out.println("won't see me");
}
}
}
But I'm not sure if this code satisfied them? Sure. The code never ends execution, but is it a true deadlock? Aren't deadlocks about synchronization? And, for example, I can also write an endless cycle, put a Thread.sleep inside and name it a "deadlock".
So the question is: is it possible to write a classic deadlock using synchronized methods but 100% guaranteed? (Please don't tell me about very, very, very likely deadlock cases. I know it.)
Thanks.
Create two resources, and have each thread try to get one before releasing the other, but in different orders. For instance:
CountDownLatch a = new CountDownLatch (1);
CountDownLatch b = new CountDownLatch (1);
void one() throws InterruptedException {
a.await();
b.countDown();
}
void two() throws InterruptedException {
b.await();
a.countDown();
}
The thread that runs one can't release b, because it's waiting for a. It'll wait forever, because the thread that runs two can't release a because it's waiting for b.
One or the classic deadlock scenarios is when you acquire locks in reverse order.
class Resource1 {
synchronized static void method1() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
Resource2.method1();
}
}
class Resource2 {
synchronized static void method1() {
Resource1.method1();
}
}
public class MultiThreadApp {
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
Resource2.method1();
}
}).start();
Resource1.method1();
}
}
public class Deadlock {
public static void main(String[] args) {
String res1 = "a";
String res2 = "s";
new Thread(
() -> {
synchronized (res1) {
try {
Thread.sleep(2);
} catch (InterruptedException e) {
}
synchronized (res2) {
}
}
}
).start();
new Thread(
() -> {
synchronized (res2) {
try {
Thread.sleep(2);
} catch (InterruptedException e) {
}
synchronized (res1) {
}
}
}
).start();
}
}
I'm getting interlocked threads in somewhat simple producer/consumer (and based on examples correct) code.
There is a thread executing this:
public void append(final Object obj) {
buffer.add(obj);
if (buffer.size() >= BUFFER_MAX_SIZE) {
insertLock.lock();
switchLock.lock();
insertLock.unlock();
bufferFull.signal();
try {
bufferSwitch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
switchLock.unlock();
}
}
There is another thread with this code:
try {
insertLock.lock();
while (true) {
switchLock.lock();
insertLock.unlock();
bufferFull.await();
switchBuffers();
bufferSwitch.signal();
insertLock.lock();
switchLock.unlock();
if (insertBuffer.size() > 0) {
db.insert(insertBuffer);
insertBuffer.clear();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
As I mentioned it is based on the producer/consumer example on the Condition API documentation. I can't detect why both threads get stuck on the conditions await method.
Is there any error ? Looks like there is something my naked eyes can't see.
Thank you,
PS: Added working code.
Thread A does
insertLock.lock();
switchLock.lock();
and Thread B does
switchLock.lock();
....
insertLock.lock();
So if Thread A acquires insertLock while B gets switchLock, neither A nor B can proceed to the next line.
It's a clasic deadlock situation. You should always make sure the locks are getting locked in the same order.
For a producer/consumer problem with threads you could look at the BlockingQueue interface and its derived classes that java offers.
For example:
package cl.mds.migracion;
import java.util.concurrent.ArrayBlockingQueue;
public class Example {
static ArrayBlockingQueue<String> buffer = new ArrayBlockingQueue<String>(5);
static class Producer implements Runnable{
#Override
public void run() {
for (int i = 0; i < 10; i++){
try {
Thread.sleep(500); //seleep 500ms to simulate producer time
buffer.put(String.valueOf(i)); //put waits the thread until there is size in the queue.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Consumer implements Runnable{
public void run() {
for (int i = 0; i < 10; i++){
try {
Thread.sleep(100); //seleep 100ms to simulate slower consumer tha producer
System.out.printf("Consuming %s ....%n",buffer.take()); //take waits the thread until there is something in the queue
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args){
System.out.printf("Starting producer/consumer ....%n");
new Thread(new Producer()).start();
new Thread(new Consumer()).start();
System.out.printf("Finishing ....%n");
}
}
public class Common {
public synchronized void synchronizedMethod1() {
System.out.println("synchronizedMethod1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronizedMethod1 done");
}
public void method1() {
System.out.println("Method 1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Method 1 done");
}
}
public class MyThread extends Thread {
private int id = 0;
private Common common;
public MyThread(String name, int no, Common object) {
super(name);
common = object;
id = no;
}
public void run() {
System.out.println("Running Thread" + this.getName());
try {
if (id == 0) {
common.synchronizedMethod1();
} else {
common.method1();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Common c = new Common();
MyThread t1 = new MyThread("MyThread-1", 0, c);
MyThread t2 = new MyThread("MyThread-2", 1, c);
t1.start();
t2.start();
}
}
Output:
Running ThreadMyThread-1
synchronizedMethod1 called
Running ThreadMyThread-2
Method 1 called
synchronizedMethod1 done
Method 1 done
I would like to find a way to prevent method1() from running when i called synchronizedMethod1. Unless I'm mistaken all methods are called and Java compiles them during and before runtime regardless if it's synchronized or not.
Should i have used a Lock object instead and/or not also make method1() a synchronized method?
I would like to find a way to prevent method1() from running when i called synchronizedMethod1
The easiest way to do this is to make method1() also be synchronized. This will mean that both methods will cause a lock on the instance of Common that they are calling. Only one thread will be able to either be calling synchronizedMethod1() or method1().
Unless I'm mistaken all methods are called and Java compiles them during and before runtime regardless if it's synchronized or not.
I don't understand this question. You really should not have to worry about the compilation or optimization phase of the JVM.
Should i have used a Lock object instead?
Usually making a method synchronized is considered not as good as using a private final lock object. Lock objects just allow you to be more fine grained in your locks. For example, with method locking, log messages and other statements that do not need protection will be synchronized as well. But if the goal is to lock the entire method then synchronizing the methods is fine.
If you want method1 and synchronizedMethod1 to be mutually exclusive then you need to guard them with the same lock. Whether this is using a Lock or simply calling synchronize on the same Object instance, the outcome is roughly the same.
On the off chance you want multiple threads to be allowed to execute method1 but not when synchronizedMethod1 is being invoked, you need a ReadWriteLock to accomplish that.
public class Common {
ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void synchronizedMethod1() {
rwLock.writeLock().lock();
try {
System.out.println("synchronizedMethod1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronizedMethod1 done");
} finally {
rwLock.writeLock().unlock();
}
}
public void method1() {
rwLock.readLock().lock();
try {
System.out.println("Method 1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Method 1 done");
} finally {
rwLock.readLock().unlock();
}
}
}