I want to run two threads one after the other, without using sleep() or Locks, but a deadlock happens! What's wrong with my code? I used wait() and notifyAll() and an Object object.
public class Test {
public static void main(String[] args) throws InterruptedException {
PrintChar a = new PrintChar('a');
PrintChar b = new PrintChar('b');
Thread ta = new Thread(a);
Thread tb = new Thread(b);
ta.start();
tb.start();
}
}
class PrintChar implements Runnable {
final Object o = new Object();
char ch;
public PrintChar(char a) {
ch = a;
}
#Override
public void run() {
for (int i = 0; i < 100; i++) {
synchronized (o) {
System.out.print(ch);
try {
o.wait();
o.notifyAll();
} catch (InterruptedException ex) {
}
}
}
}
}
Running your code, and looking at it, I've found that each thread you generated was generating and synchronizing to its own object, therefore preventing them from notifying each other. I've also found that you wait before notify, so you do not ever get to invoke o.notifyAll(), as o.wait() stops it first.
Change final Object o = new Object() to static final Object o = new Object(), and switch the places of o.wait() and o.notifyAll()
I think the synchronized block is causing the deadlock. Cos it won't let the other thread start until current one finished. You are using wait() method to make the current thread wait. Ok, it will wait but since it is in synchronized block, it will be in the current thread forever never let any other thread to came into existence because of synchronized.
One thing you can do to make the other thread work is using Thread.stop. Try calling stop method in current thread's reference. But I am not sure whether it will let the current thread to start again.
Related
I'm trying to create thread safe queue in java. I've come across this example:
class ProducerConsumer<T> {
private static final int BUFFER_MAX_SIZE = 42;
private List<T> buffer = new LinkedList<>();
synchronized void produce(T value) throws InterruptedException {
while (buffer.size() == BUFFER_MAX_SIZE) {
wait();
}
buffer.add(value);
notify();
}
synchronized T consume() throws InterruptedException {
while (buffer.size() == 0) {
wait();
}
T result = buffer.remove(0);
notify();
return result;
}
}
I'm new to java. In my understanding those two 'synchronized' keywords would prevent contention inside each method, but not when both methods are called simultaneously. E.g. thread P calls produce, locks method, thread C calls consume, locks other method, then one tries to extract element from list, another tries to insert element, thread exception arises.
My question: Is this example broken?
Or maybe I'm missing something and it's ok.
JLS, §17.1 is quite explicit about the mechanism:
...
A synchronized method (§8.4.3.6) automatically performs a lock action when it is invoked; its body is not executed until the lock action has successfully completed. If the method is an instance method, it locks the monitor associated with the instance for which it was invoked (that is, the object that will be known as this during execution of the body of the method). If the method is static, it locks the monitor associated with the Class object that represents the class in which the method is defined. If execution of the method's body is ever completed, either normally or abruptly, an unlock action is automatically performed on that same monitor.
...
Thus, it is guaranteed that at one point in time on one object at most one thread is executing either produce(...) or consume(). It is not possible that, at one point in time, one thread executes produce(...) on an object while another thread executes consume() on the same object.
The call to wait() in consume() releases the intrinsic lock and blocks execution. The call to notify() in produce(...) notifies one wait()ing thread (if any), so it can fight for the lock as soon as the lock is released by the current owner. Notice that a call to notify() does not release the intrinsic lock. It just wakes up a wait()ing thread. This can be made observable with the following code snippet:
class Ideone {
private static final Object lock = new Object();
public static void main(String[] args) {
printWithThreadNamePrefix("Start");
Thread waiter = new Thread(Ideone::waiter);
waiter.start();
// Give waiter some time to a) start and b) acquire the intrinsic lock
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
final Thread notifier = new Thread(Ideone::notifier);
notifier.start();
while (true) {
try {
waiter.join();
break;
} catch (InterruptedException e) {
}
}
printWithThreadNamePrefix("End");
}
private static void waiter() {
synchronized (lock) {
printWithThreadNamePrefix("Waiting...");
while (true) {
try {
lock.wait();
break;
} catch (InterruptedException e) {
}
}
printWithThreadNamePrefix("... done waiting");
}
}
private static void printWithThreadNamePrefix(String msg) {
System.out.println(String.format(
"%s: %s",
Thread.currentThread().getName(),
msg));
}
private static void notifier() {
synchronized (lock) {
printWithThreadNamePrefix("notifying");
lock.notify();
while (true) {
}
}
}
}
Ideone demo
The program will never terminate. Although thread two calls notify(), it then enters an endless loop, never actually releasing the intrinsic lock. Thus, one never has a chance to acquire the intrinsic lock, and the program "hangs" (it is neither a deadlock, nor a livelock, it simply cannot proceed).
The things I recommend to change are:
declare private List<T> buffer additionally as final
call notifyAll() instead of notify() in order to wake all waiting threads (they will still execute sequentially, for details see this question by Sergey Mikhanov and its answers)
I try to create 10 threads in a 10-times loop, and want to see the conflicts print out when I didn't assign the synchronized on the method.
This is my code
public class SingletonService {
private static SingletonService singleton = null;
public static SingletonService getInstance() {
if (singleton == null) {
synchronized(SingletonService.class) {
if (singleton == null) {
singleton = new SingletonService();
return singleton;
}
}
}
return singleton;
}
public void testMethod() {
boolean flag = true;
System.out.println("start");
if (flag == false) {
System.out.println(">>>>>>>>>>>>>>>Error");
}
flag = false;
System.out.println("over");
}
}
Below is the thread which get the service and call the testMethod()
public class Transferable extends Thread {
private SingletonService service = null;
public Transferable(SingletonService aService) {
service = aService;
}
public void run() {
System.out.println("Service Start");
service.testMethod();
System.out.println("Service End");
}
}
Now which confused me a lot is that when I try to create the thread in a loop like
for (int i = 0; i < 10; i ++) {
Transferable t1 = new Transferable(service);
t1.run();
Thread.sleep(10);
}
then the callMethod() in the service will be executed sequencelly and will not affect each other (also the error message will not be thrown out)
But when I try to create the thread manually like
Transferable t1 = new Transferable(service);
Transferable t2 = new Transferable(service);
Transferable t3 = new Transferable(service);
Transferable t4 = new Transferable(service);
Transferable t5 = new Transferable(service);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
The error message is printed out and the start-end sequence also become disorder...
Any one can help to solve my problem the tell the detail?
Thanks^BR
There are a number of things that contribute to the behavior of your two examples.
First, SingletonService.testMethod() defines flag as a local variable. Thus, it cannot really be used as a flag to check thread conflicts. I don't see how you could ever get an error output. This flag should be a field.
Second, the looped example calls the run() method of the thread, while the manual example calls the start() method. start() will create a new thread which will in turn call the run() method. run() will simply execute your Transferable.run() method in the current thread, thus enforcing a sequential operation.
Third, if you were change the aforementioned things, you would still have a Thread.sleep(10) call in each loop, meaning that between starting one thread and the next, you wait 10 milliseconds which is more than enough time for the first thread to finish.
Have a look at the Thread java se documentation site
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html and in particular the start() method
start(): Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
Calling run() inside your loop doesn't cause the Thead to execute. In contrary, run() is executed in the main Thread and that's the reason why execution is sequential and not in parallel as you would expect.
Please try replacing run() with start() in your for loop.
When I try to execute the piece of code, I am getting output like 12221121212121221212. When I declare the method as synchronized, it should not allow the other thread to take over the control
package com.test;
public class TestProject extends Thread {
public void run() {
synchronized (this) {
for (int i = 0; i < 10; i++) {
System.out.print(getName());
}
}
}
public static void main(String[] args) throws InterruptedException {
TestProject myProject = new TestProject();
TestProject myProject1 = new TestProject();
myProject.setName("1");
myProject1.setName("2");
myProject.start();
myProacject1.start();
}
}
So, how do I alter the code to get a output of 11111111112222222222 or 22222222221111111111 in sequential format?
You are synchronizing on this, i.e. on the TestProject object. Since you have two separate objects, you have two separate locks. Consequently, both threads can enter the synchronized section irrespective of what the other thread is doing.
To synchronize across instances of TestProject you need a static lock:
public class TestProject extends Thread {
private static final Object lock = new Object();
public void run() {
synchronized (lock) {
...
Java uses biased locking by default. This means a lock will favour the last thread to access a lock. If you consider that one thread can start, run and finish before the other even starts I would expect you get one thread running to completion before the other starts most of the time.
I have just noticed you lock outside the loop. This will guarantee you also run one thread to completion before the other starts.
This is how you can enforce fair alternation of threads.
public class TestProject implements Runnable {
private final Lock lock;
public TestProject(Lock lock) {
this.lock = lock;
}
public void run() {
for (int i = 0; i < 10; i++) {
lock.lock();
try {
System.out.print(Thread.currentThread().getName());
} finally {
lock.unlock();
}
}
}
public static void main(String... ignored) {
Lock lock = new ReentrantLock(true);
new Thread(new TestProject(lock), "1").start();
new Thread(new TestProject(lock), "2").start();
}
}
can print
12121212121212121212
Note: if you make the lock non-fair you can get (change the true to false)
11111111112222222222
Note: if you want fair alternation between two tasks, it much simpler to use one thread and a loop.
public static void main(String... ignored) {
for (int i = 0; i < 10; i++) {
// task 1
System.out.print("1");
// task 2
System.out.print("2");
}
}
you can also use join method on myProject1 so that it waits for the other thread to finish
these are the following method that can be used to achieve synchronization among the thread
1). use a static global lock and pass that object variable as argument to the synchronized block
2). use join()
3). create a instance for the Object class and pass that as an argument to the synchronized block like this Object myObject = TestProject.class now pass myObject to the synchronized block
using either of the above ways we can achieve synchronization
I want to restart a thread for some use, for example in the below code.
class Ex13 implements Runnable {
int i = 0;
public void run() {
System.out.println("Running " + ++i);
}
public static void main(String[] args) throws Exception {
Thread th1 = new Thread(new Ex13(), "th1");
th1.start();
//th1.join()
Thread th2 = new Thread(th1);
th2.start();
}
}
When I'm executing the above program , some time i'm getting the output as
Running 1
Running 2
and some time i'm getting only
Running 1
After few run i'm getting only
Running 1 as output.
I'm totally surprise about this behavior. Can any one help me understand this.
if I put the join() then i'm getting only Running 1.
You reuse Thread instance, not Runnable. Thread overwrites its run() method to
public void run() {
if (target != null) {
target.run();
}
}
Where target is the Runnable that you give to the constructor. besides that, Thread has an exit() method that is called by the VM, and this method sets target to null (the reason is this bug). So if your first thread has the chance to finish its execution, its run() method is pretty much empty. Adding th1.join() proves it.
If you want to keep some state, you need to keep reference to your Runnable instance, not the Thread. This way run() method will not be altered.
I don't know why do you need this, but (please note that this code doesn't ensure that th1 is ALWAYS executed before th2, though) :
public static class Ex13 implements Runnable {
AtomicInteger i = new AtomicInteger(0);
CountDownLatch latch;
Ex13(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Running " + i.incrementAndGet());
latch.countDown();
}
}
public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(2);
Ex13 r = new Ex13(latch);
Thread th1 = new Thread(r, "th1");
th1.start();
Thread th2 = new Thread(r);
th2.start();
latch.await(); // wait until both theads are executed
System.out.println("Done");
}
You want the incrementing of i to be synchronized, i.e.
public class Ex13 implements Runnable {
int i=0;
public void run() {
System.out.println("Running "+ increment());
}
private synchronized int increment() {
return ++i;
}
}
The Java Tutorial has a very nice explanation of this given a very similar scenario. The problem is that incrementing a variable is not an atomic operation. Each thread needs to read the current state of i before setting it to the new value. Restricting access to incrementing the variable to one thread at a time assures you will get consistent behavior.
To see whats happening in the System.out.println you can also print the thread name:
Thread t = Thread.currentThread();
String name = t.getName();
System.out.println("name=" + name);
I see you call the two threads with the same runnable object, so they will both use the same "i" variable, in order for you to get Running 1 Running 2 you need to synchronize "i"
Isn't it possible that notify() in another thread gets called before the wait() in one thread?
It's happening with me.
A client requests a value from a target and waits on a result variable RV.
In case the target is the client itself, I update RV with the correct result and call notify() on RV in another thread.
class EMU {
ResultVar RV;
Address my_address;
ResultVar findValue(String key) {
String tgt = findTarget(key);
sendRequest(tgt, key);
synchronized(RV) {
RV.wait();
}
return RV;
}
Runnable Server = new Runnable() {
public void run() {
//code to receive connections. Assume object of type Request is read from the stream.
Request r = (Request) ois.readObject();
if(r.requesterAddr.compareTo(my_address) == 0) {
String val = findVal(key);
RV.putVal(val);
synchronized(RV){
RV.notify();
}
}
}
};
}
The problem is that before the requester has completed all the "networking" (sendReqest in the above example) with itself, the result is updated in the result variable. When the requester thread now calls wait(), the program doesn't continue, since notify has already been called.
How can we prevent it?
You check some flag before waiting (in a loop), see the tutorial: http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
Nothing stops you calling notify on an object that's not being waited by another thread.
It sounds like what you want is a wait only if some condition holds. For example:
synchronized (results) {
while (!results.hasResults()) {
// no results yet; wait for them
try {
results.wait();
} catch (InterruptedException ie) { /* ignore */ }
}
}
I'd strongly recommend not re-inventing the wheel.
Java's Future interface is designed for results that may only arrive later, and the FutureTask class implements this interface.
Have the first thread obtain access to the Future and get the second thread to run the FutureTask, and all of this stuff gets handled for you. You also get timeout support for free.
Use some condition before going to wait() and make sure that condition is thread safe :)
class EMU{
ResultVar RV;
Address my_address;
volatile boolean condition = true;
ResultVar findValue(String key){
String tgt = findTarget(key);
sendRequest(tgt, key);
synchronized(RV){
while(condition == true)
{
RV.wait();
}
}
return RV;
}
Runnable Server = new Runnable(){
public void run(){
//code to receive connections. Assume object of type Request is read from the stream.
Request r = (Request) ois.readObject();
if(r.requesterAddr.compareTo(my_address) == 0){
String val = findVal(key);
RV.putVal(val);
synchronized(RV){
condition = false;
RV.notify();
}
}
}
};
Let me first break down the code to a minimum reproducable:
public static void main(String[] args) throws Exception {
Object RV = new Object();
new Thread() {
#Override
public void run() {
synchronized (RV) {
RV.notify();
}
}
}.start();
Thread.sleep(1_000);
synchronized (RV) {
RV.wait();
}
}
This method will theoretically never end and the program will never quit. It shall be a dispute if this is a deadlock.
My solution is to create a second lock:
public static void main(String[] args) throws Exception {
Object RV = new Object();
Object lock = new Object();
new Thread() {
#Override
public void run() {
synchronized (lock) {
lock.wait();
}
synchronized (RV) {
RV.notify();
}
}
}.start();
Thread.sleep(1_000);
synchronized (RV) {
synchronized (lock) {
lock.notify();
}
RV.wait();
}
}
Lets inspect what the threads are doing while the main-thread is waiting one second:
The custom Thread will first join the synchronized(lock) block.
Then the lock will causes the custom Thread to wait.
After 1 second the main-thread is joining a RV-synchronization.
The lock gets notified and causes the custom Thread to continue the work.
The custom thread leaves the synchronized(lock) block.
The main thread will RV-wait-lock.
The custom thread notifies the RV-lock to continue.
The program ends.