Threads notify not working after wait problem - java - java

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();
}
}

Related

execute Thread.interrupt() Object.notify() at the same time, why does has two results?

public class WaitNotifyAll {
private static volatile Object resourceA = new Object();
public static void main(String[] args) throws Exception {
Thread threadA = new Thread(new Runnable() {
#Override
public void run() {
synchronized (resourceA) {
try {
System.out.println("threadA begin wait");
resourceA.wait();
System.out.println("threadA end wait");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread threaB = new Thread(new Runnable() {
#Override
public void run() {
synchronized (resourceA) {
System.out.println("threadC begin notify");
threadA.interrupt();
resourceA.notify();
}
}
});
threadA.start();
Thread.sleep(1000);
threaB.start();
System.out.println("main over");
}
}
There are two possible result here:
throws InterruptedException
normal termination
why?
I don't understand. when threadA is interruptted ,result should throws InterruptedException. but sometimes execute this program, it can normal finish.
environment: java8, mac
When a thread receives both an interrupt and a notify, the behaviour may vary.
Please refer to https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.2.3
Credit - Alex Otenko on the Concurrency Interest mailing list
Because of reordering. In normal termination compiler reordered instruction interrupt and notify, interruption invokes on working thread and no interrupted exception throws.
Try to forbid reordering with reading volatile variable and you always get interrupted exception.
public class WaitNotifyAll {
private static volatile Object resourceA = new Object();
public static void main(String[] args) throws Exception {
Thread threadA = new Thread(new Runnable() {
#Override
public void run() {
synchronized (resourceA) {
try {
System.out.println("threadA begin wait");
resourceA.wait();
System.out.println("threadA end wait");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread threaB = new Thread(new Runnable() {
#Override
public void run() {
synchronized (resourceA) {
System.out.println("threadC begin notify");
threadA.interrupt();
System.out.print(resourceA);
resourceA.notify();
}
}
});
threadA.start();
Thread.sleep(1000);
threaB.start();
System.out.println("main over");
}
}

Is it possible to write a guaranteed classic deadlock with synchronized methods?

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();
}
}

Trying to create a deadlock between two threads

For creating a deadlock in between two threads by accessing print method into Threads. I have used cyclic Barrier so that both of the thread starts at same time. If I am correct my print method is not taking time, for that reason it is getting shared by the two threads and not causing a Deadlock.
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class TWOTHREADDEADLOCLK {
static int b =0;
synchronized static void print()
{
System.out.println(Thread.currentThread().getName() + " " + b);
}
synchronized static int getb()
{
print();
return b;
}
synchronized static void updateb()
{
print();
b=b+10;
}
public static void main(String[] args) {
final CyclicBarrier bar = new CyclicBarrier(2);
Thread thread1 = new Thread(new Runnable(){
#Override
public void run()
{
try {
bar.await();
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch ( BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
while(true)
print();
}
});
Thread thread2 = new Thread(new Runnable(){
#Override
public void run()
{try {
bar.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
while(true)
getb();
}
});
thread1.start();
thread2.start();
}
}
You can't create a deadlock with a single barrier. The idea behind a deadlock is to have (at least) two threads, each one holding a different lock and attempting to take a lock on the other one. E.g., consider this simple example:
public class TwoLockRunnable implements Runnable {
private Lock lockInConstructor;
private Lock lockInRuntime;
public TwoLockThread(Lock lockInConstructor, Lock lockInRuntime) {
this.lockInConstructor = lockInConstructor;
this.lockInRuntime = lockInRuntime;
this.lockInConstructor.lock();
}
#Override
public void run() {
lockInRuntime.lock();
System.out.println("After the lock in run()");
}
public static void main(String[] args) {
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
TwoLockRunnable runnable1 = new TwoLockThread(lock1, lock2);
TwoLockRunnable runnable2 = new TwoLockThread(lock2, lock1);
new Thread(runnable1).start();
new Thread(runnable2).start();
}
}
The first thread locks lock1 in its constructor and the second locks lock2 in its constructor. The first thread then tries to lock lock2 when its run - but it can't since lock is held by the other thread. Similarly, the second thread attempts to lock lock1 when its run, and fails for the same reason. Thus, you get a deadlock, and the message "After the lock in run()" is never printed.
like Mureinik's, this is the 'synchronized' demo:
public class DeadLockAATest {
static void methodA(DeadLockAATest d1, DeadLockAATest d2) {
synchronized (d1) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (d2) {
System.out.println("\t\t\tmethodA:" + Thread.currentThread().getName());
}
}
}
public static void main(String[] args) {
DeadLockAATest d1 = new DeadLockAATest(), d2 = new DeadLockAATest();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("t1-start:" + Thread.currentThread().getName());
methodA(d1, d2);
System.out.println("t1-end:" + Thread.currentThread().getName());
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("t2-start:" + Thread.currentThread().getName());
methodA(d2, d1);
System.out.println("t2-end:" + Thread.currentThread().getName());
}
});
t1.start();
t2.start();
System.out.println("deadlock...");
}
}
the deadlock output(just one contion, maybe t2 starts first):
t1-start:Thread-0
deadlock...
t2-start:Thread-1
you can replace
methodA(d2, d1);
to
methodA(d1, d2);
and this will output:
t1-start:Thread-0
t2-start:Thread-1
deadlock...
methodA:Thread-0
t1-end:Thread-0
methodA:Thread-1
t2-end:Thread-1
and this is not deadlock, hope to help you.

Having troubles with threads and semaphors in JAVA

I am new to threading and semaphors, and I have some problem in synchronizing threads. For example, in the following code I want to do a pretty simple thing. To let one thread run, while other waits. For example, if it starts with the first thread, I want the second to wait for the first one to finish and then start. I really don't know what am I doing wrong.
Here is the code :
import java.io.*;
import java.util.concurrent.Semaphore;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Semaphore binaren = new Semaphore(1);
Runnable t1 = new T2(binaren);
Thread a = new Thread(t1);
Thread a2 = new T1(binaren);
System.out.println(binaren.availablePermits());
a.start();
a2.start();
}
}
class Work {
private static int a = 4;
public synchronized static void QQR(String s1)
{
for(int i=0;i<100;i++)
System.out.println(s1+" : "+(a++));
}
}
class T1 extends Thread
{
Semaphore sem;
public T1(Semaphore s1)
{
sem=s1;
}
public void run()
{
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T1");
sem.release();
notifyAll();
}
}
}
class T2 extends Thread
{
Semaphore sem;
public T2(Semaphore s1)
{
sem=s1;
}
#Override
public void run() {
synchronized(this) {
if(!sem.tryAcquire()){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Work.QQR("T2");
sem.release();
notifyAll();
}
}
}
The problem is that notify and notifyAll only wake up threads holding locks on the monitor being notified. But the t1 and t2 instances are waiting on themselves and are never awoken. You can have them wait on the semaphore for this simple test or introduce a new shared object to see how it works.
Use
sem.wait();
and
sem.notifyAll();
You can use Thread.join() on the first thread so that second thread will wait till the execution of this instance is not completed.

unable to correctly interpret wait and notify program

When I try to run the below code, the code does not enter into either the block with wait() nor the block with notifyAll(). However, the result of the program is "A B" or "B A". I do not understand what was I missing in the program.
public class threads1 extends Thread {
static Object obj = new Object();
public threads1(String str) {
super(str);
}
public void run() {
try {
waitforsignal();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void waitforsignal() throws InterruptedException {
synchronized (obj) {
System.out.println(Thread.currentThread().getName());
while (Thread.currentThread().getName() == "A") {
System.out.println("into wait");
obj.wait();
}
if ((Thread.currentThread().getName() == "B")) {
System.out.println("had notified");
obj.notifyAll();
}
}
}
public static void main(String... strings) throws InterruptedException {
Thread t1 = new threads1("A");
Thread t2 = new threads1("B");
t1.start();
t2.start();
}
}
It has nothing to do with threads: you are comparing strings with == instead of equals.
Once you have fixed that, note that for thread t1:
Thread.currentThread().getName().equals("A")
will always be true, so your program will never finish...

Categories