This could be a newbie question - I am running into a deadlock situation while using BlockedLinkedQueue - Here is a snipped of my code:
public class mytest {
private BlockedLinkedQueue myQueue;
public synchronized void consumer() {
...
myQueue.take()
...
}
public synchronized void producer() {
...
myQueue.put()
...
}
}
I am noticing that sometimes I run into deadlock. A lot of producer() threads are waiting on the method monitor, and one consumer is blocked on take(). Is this expected? I know that I don't really have to synchronize BLockedLinkedQUeue - but I have lot of other objects and I need to synchronize these methods..
Yes, this deadlock is expected. It occurs when consumer() is called with the empty queue. In this case consumer() holds lock on "this" and waits for an object from myQueue. Same time any producer() can't take lock on "this" (held by consumer) and thus can't put any object to myQueue, which prevents consumer from taking an object.
To resolve deadlock, you may make only part of methods synchronized or use simple queue and implements your own waiting for a data.
Example of partial synchronization:
public class mytest {
private BlockedLinkedQueue myQueue;
public void consumer() {
synchronized(this) {
...
}
myQueue.take();
synchronized (this) {
...
}
}
public void producer() {
synchronized(this) {
...
}
myQueue.put()
synchronized(this) {
...
}
}
}
In this case, lock on "this" is released during myQueue operation. And it will allow producer() to procede it's way and put an object to the queue.
Second example:
public class mytest {
private Queue myQueue;
public synchronized void consumer() {
...
while (myQueue.isEmpty()) {
this.wait();
}
myQueue.take()
...
}
public synchronized void producer() {
...
myQueue.put()
this.notify();
...
}
}
In this example lock on "this" is released during call to this.wait() (see Object.wait() for details) and it allows producer to put object to the queue. Also, producer wakes up one of consumers waiting for data.
Please, note, that in both cases producer method will be executed when only a "half" of consumer method is executed. I.e. consumer method is no more atomical at all, but only at it halfs. And if you need atomicity of the consumer, then you should think about better specification of the producer/consumer methods, because described deadlock is logical flaw in the "synchronization". You can't put object during execution of "atomic" consumer() method and at the same time consumer() requires object to be in the queue.
BlockedLinkedQueue? I think you mean LinkedBlockingQueue.
LinkedBlockingQueue is thread safe and you should not be hiding it behind the synchronization method modifiers. Removing those will may end your deadlock issue. Liberal use of synchronization is generally not a good idea--keep it to a minimum, just where you need it.
As maxkar points out, BlockingQueue.take() waits until there is something in the queue.
Retrieves and removes the head of this
queue, waiting if necessary until an
element becomes available.
If you are adamant about keeping the synchronization on the consumer() method in your class, consider using BlockingQueue.poll(long timeout, TimeUnit unit). This will allow you to craft logic that gracefully deals with an empty queue.
Related
Proxy will be called from multiple thread, and Proxy.setWorker() may be called at some time, does anyone know if below implementation will cause problem?
class Worker {
void methodA() {
...
}
void methodB() {
...
}
};
… and …
class Proxy {
volatile Worker mWorker;
final boolean cond= true;
public void setWorker(Worker worker) {
mWorker = worker;
}
void methodA() {
if(cond)
mWorker.methodA();
}
void methodB() {
if(cond)
mWorker.methodB();
}
}
You get a data race when there are 2 threads doing a read/write or write/write to the same field and these reads/writes are not ordered by the happens-before relation (so there is no happens-before edge between them).
The 'worker' field is volatile, so there is a happens-before edge due to the volatile variable rule; hence, there is no data-race.
I would make the 'cond' field final if possible to prevent confusion. If you would modify the 'cond' field, then your code could have a data-race unless you make it volatile.
It depends on if you have a separate Proxy for each thread. If you do you are fine. If you don't and you try and call setWorker from two places at the same or if you try and one of the methods while setting the worker or if either of the methods modify proxy or worker you will have some data race issues.
I've read this topic, and this blog article about try with resources locks, as the question popped in my head.
But actually, what I'd rather like would be a try with lock, I mean without lock instantiation. It would release us from the verbose
lock.lock();
try {
//Do some synchronized actions throwing Exception
} finally {
//unlock even if Exception is thrown
lock.unlock();
}
Would rather look like :
? implements Unlockable lock ;
...
try(lock) //implicitly calls lock.lock()
{
//Do some synchronized actions throwing Exception
} //implicitly calls finally{lock.unlock();}
So it would not be a TWR, but just some boilerplate cleaning.
Do you have any technical reasons to suggest describing why this would not be a reasonable idea?
EDIT : to clarify the difference between what I propose and a simple synchronized(lock){} block, check this snippet :
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
public static void main(String[] args) {
ReentrantLock locker =new ReentrantLock();
Condition condition = locker.newCondition();
Thread t1 = new Thread("Thread1") {
#Override
public void run(){
synchronized(locker){
try {
condition.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Thread1 finished");
}
}
} ;
Thread t2 = new Thread("Thread2") {
#Override
public void run(){
synchronized(locker){
Thread.yield();
condition.signal();
System.out.println("blabla2");
}
}
} ;
t1.start();
t2.start();
}
}
Execution will result in a IllegalMonitorStateException, so lock() and unlock() methods are not implicitly called within synchronized block.
If you had to deal with a simple case like that, where the pattern of locking/unlocking was limited to a narrow scope like this, you probably don't want to use the more complicated Lock class and probably should just be using the synchronized keyword, instead. That being said, if for some reason you needed this with the more complicated Lock object, it should be relatively straight-forward to create a wrapper around Lock that implements the AutoCloseable interface to be able to do just that. Example:
class AutoUnlock implements AutoCloseable {
private final Lock lock;
public static AutoUnlock lock(Lock lock) {
lock.lock();
return new AutoUnlock(lock);
}
public static AutoUnlock tryLock(Lock lock) {
if (!lock.tryLock()) {
throw new LockNotAcquiredException();
}
return new AutoUnlock(lock);
}
#Override
public void close() {
lock.unlock();
}
private AutoUnlock(Lock lock) {
this.lock = lock;
}
}
With a wrapper like the above, you could then do:
try (AutoUnlock autoUnlock = AutoUnlock.lock(lock)) {
// ... do whatever that requires the lock ...
}
That being said, the Lock class is typically used for very complicated locking scenarios where this wouldn't be particularly useful. For example, Lock objects may be locked in one function in a class and later unlocked in another function (e.g. locking a row in a database in response to an incoming remote procedure call, and then unlocking that row in response to a later RPC), and thus having such a wrapper or making a Lock AutoCloseable, itself, would be of limited use for the way it is actually used. For more simple scenarios, it's more common to just use an existing concurrent datastructure or use synchronized.
This answer serves to explain the behavior of your edit. The purpose of synchronized is to lock the monitor of the given object when the thread enters the block (waiting if it isn't available) and releasing it when the thread exits the block.
Lock is a higher level abstraction.
Lock implementations provide more extensive locking operations than
can be obtained using synchronized methods and statements.
You can use it to lock across method boundaries. synchronized is not able to do this so a Lock cannot be implemented solely with synchronized and no implementation I've ever seen uses it. Instead, they use other patterns, like compare and swap. They use this to set a state atomically within a Lock object which marks a certain thread as the owner of the lock.
In your code snippet, you try to invoke
condition.signal();
in a thread which does not own the Lock from which the condition was created. The javadoc states
An implementation may (and typically does) require that the current
thread hold the lock associated with this Condition when this method
is called. Implementations must document this precondition and any
actions taken if the lock is not held. Typically, an exception such as
IllegalMonitorStateException will be thrown.
That's what happened here.
Executing
synchronized (lock) {}
makes the current thread lock (and then release) the monitor on the object referenced by lock. Executing
lock.lock();
makes the current thread set some state within the object referenced by lock which identifies it as the owner.
Hallo I've been debugging my code for a whole day already, but I just can't see where could be wrong.
I use SerialPortEventListener on a main thread, in a working thread I have a client socket communicating to a server.
Since after this working thread reach return, I still need some wrap up work done in the main thread, i want to create a "pseudothread" that wait in the main thread until the it is notified from the listener onEvent method.
but this pseudothread seems to be waiting forever.
I checked the locked thread pseudoThread, they should have the same object id in the Runnable and in Listener class.
"PseudoThread waiting" got displayed, but PseudoThread awake is never showed.
Console output shows:
PseudoThread waiting
..
..
false notified pseudothread.
PS if I create a lock in Main class with public final Object lock = new Object(); and replace all main.pseudoThread with main.lock, I get java.lang.IllegalMonitorStateException.
private class Pseudo implements Runnable{
Main main;
public Pseudo(Main main) {
this.main = main;
}
#Override
public void run() {
synchronized(main.pseudoThread){
try {
System.out.println("PseudoThread waiting");
main.pseudoThread.wait();
System.out.println("PseudoThread awake");
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}
}
in main method:
public static void main(String[] args) {
Main main = new Main();
main.initArduino();
//more code. including starting the working thread
main.pseudoThread = new Thread(main.new Pseudo(main));
main.pseudoThread.start();
try {
main.pseudoThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void initArduino() {
arduino = new Arduino(this);
if(!arduino.initialize())
System.exit(1);
}
and in the listener class (which also runs in main thread)
//class constructor;
public Arduino(Main Main){
this.main = Main;
}
//listening method
public void serialEvent(SerialPortEvent oEvent){
//some code to interract with working thread.
record();
}
private void record(){
synchronized(main.pseudoThread){
main.pseudoThread.notify();
System.out.println("notified pseudothread.");
}
}
Without looking too deeply into what might actually be happening, I can see that your use of wait()/notify() is all wrong. Probably you are experiencing a "lost notification." The notify() function does nothing if there is no thread waiting for it at the moment when it is called. If your serialEvent() function calls notify() before the other thread calls wait(), then the notification will be lost.
Consider this example:
class WaitNotify() {
private final Object lock = new Object();
private long head = 0;
private long tail = 0;
public void consumer() {
synchronized (lock) {
while(head == tail) {
lock.wait();
}
doSomething();
count head += 1;
}
}
public void producer() {
synchronized (lock) {
tail += 1;
lock.notify();
}
}
}
The essential points are:
(1) The consumer() function waits for some relationship between data to become true: Here, it waits for head != tail.
(2) The consumer() function waits in a loop. There's two reasons for that: (a) Many programs have more than one consumer thread. If consumer A wakes up from the wait(), there's no guarantee that consumer B hasn't already claimed whatever it was that they both were waiting for. And (b) The Java language spec allows foo.wait() to sometimes return even when foo.notify() has not been called. That's known as a "spurious wakeup." Allowing spurious wakeups (so long as they don't happen too often) makes it easier to implement a JVM.
(3) The lock object is the same lock that is used by the program to protect the variables upon which the condition depends. If this example was part of a larger program, you would see synchronized(lock) surrounding every use of head and tail regardless of whether the synchronized code is wait()ing or notify()ing.
If your own code obeys all three of the above rules when calling wait() and notify(), then your program will be far more likely to behave the way you expect it to behave.
As suggested by james it could be lost notification case or it could be that.. Two Threads 1- Your Main Thread and 2- Pseudo thread Are waiting on the same Thread Instance Lock (main.pseudoThread)( Main thread waits on the same lock by calling join method).
Now you are using notify which wakes the Main thread from join method and not the one
waiting in your Pseudo. To check for the second case try calling notifyall in record this will either
confirm the second case or will rule this possibility.
Anyways please refactor your code not to use synch on Thread instance its bad practice. Go for ReentrantLock or CoundDownLatch something.
Usage of notify and wait seem to be incorrect. Method name notify can be a bit misleading because it is not for general purpose "notifying". These methods are used to control the execution of synchronization blocks. Wait will allow some other thread to synchronize with same object while current threads pauses. Basically this is used when some resource is not available and execution can not continue. On the other hand notify will wake one waiting thread wake from wait after notifying thread has completed its synchronized-block. Only one thread can be in synchronized block of the same object at the same time.
If the idea is just keep the main program running until notified then semaphore would be much more appropriate. Something like this.
public void run() {
System.out.println("PseudoThread waiting");
main.semaphore.acquireUninterruptibly();
System.out.println("PseudoThread awake");
}
//...
private void record(){
main.semaphore.release();
}
//...
public static void main(String[] args) {
main.semaphore = new Semaphore(0);
//...
}
In java, I have 2 threads in my client, one is controlling the network flow, the other one is processing the messages, draws game etc. What I am trying to do is when a packet comes, the network thread will call messageReceived method of the game thread, containing the message as parameter. Will it block networking thread if i make the function messageReceived as synchronized and there are 2 packets sequentally come before messageReceived function ends, or it doesn't block and my packet is lost because network thread couldn't call messageReceived function which is already being used by game thread ?
When you use the synchronized keyword to sync a code section, then when another thread comes in that wants access to that section it will block until it can get access.
Correct, you're blocking on the IO thread. You want to only do light work on messageReceived() because of that ... perhaps only queue the message in some sort of FIFO for the processing thread to work on later. Your sync blocks should have as small a footprint as possible.
If a thread calls a synchronized method in a class, all the other threads will be blocked to call any synchronized method in that class because the object lock is not available. If your messageReceived is not working on any shared resource then keep it non-synchronized. In case it is using some shared resource then try to minimized the synchronized code by wrapping that code in synchronized block.
It sounds like you are attempting to solve a problem that could be easily avoided if you used a more mainstream design pattern such as the Observer Pattern. http://en.wikipedia.org/wiki/Observer_pattern
Its easy to conceptualize but im more of a visual person. Heres a bit of code that helped me long ago understand what excatly syncorized did and how it worked. If you watch the output you will see when you add the synchronized attribute to the print function that you never see As and Bs mixed. but when you remove it you will see a much different output. It should be straight forward once you see it.
public class Main {
public static void main(String[] args) {
(new ThreadA()).start();
(new ThreadB()).start();
}
// try it with removing the synchronized: public static void print(String str) {
public static synchronized void print(String str) {
for(int i = 0; i<100; i++)
System.out.print(str);
System.out.println();
}
public static class ThreadA extends Thread {
public void run() {
while(true) {
print("A");
}
}
}
public static class ThreadB extends Thread {
public void run() {
while(true) {
print("B");
}
}
}
}
Yes, synchronized blocks a thread if the implicit lock has already locked by another thread. But there is a non-blocking alternative - java.util.concurrent.locks.Lock that is more flexible
Lock.tryLock()
acquires the lock only if it is free at the time of invocation
and
Lock.tryLock(long time, TimeUnit unit)
acquires the lock if it is free within the given waiting time and the current thread has not been interrupted.
I have multithreaded application. Sometime in some thread happens exception for external network reason. I think use e.g. wait(60000) - 1 minute to re-connect.
Should I explicitly put in synchronized method e.g.:
public void synchronized reconnect(){
wait(60000);
................. }
or it possible:
public void reconnect(){
wait(60000);
................. }
Thanks.
As Eugene wrote, current thread must acquire lock on object. It is not necessary done by synchronized method. You also may acquire lock by explicit synchronizing:
public void reconnect() {
// some code
synchronized (this) {
wait(60000);
}
// some other code
}
It depends on that you need to achieve.
It has to be! You must acquire the lock of the Object before you can actually wait.
Cheers,Eugene.