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.
Related
I stumbled across this method in a project i am working on, and immediately thought that something is wrong. I had the feeling this can't be any proper idom for anything.
But i don't get the intentions and implications of this. Can this be refactored? Does the second synchronized make any sense - and isn't the third synchronized redundant/unnecessary?
I am just starting to get into advanced concurrent/threadsafe programming in java - a detailed explanation why this makes sense or no sense and why is much appreciated!
#Override
public synchronized void run() {
synchronized (this.market) {
synchronized (this.market.getWallet()) {
this.handler.handleEvent(new WalletLecherEvent(this, market,
market.leechWallet()));
}
}
}
thanks in advance
edit, in order to supply more context:
public class WalletLeecherWorker extends Worker {
private IAbstractMarketAPI market = null;
private Thread thread = null;
public WalletLeecherWorker(IEventHandler handler, IAbstractMarketAPI market) {
super(handler);
this.market = market;
}
public void startThread() {
if (thread != null)
return;
thread = new Thread(this);
thread.start();
}
public MARKETs getMarket() {
return this.market.getName();
}
#Override
public synchronized void run() {
synchronized (this.market) {
synchronized (this.market.getWallet()) {
this.handler.handleEvent(new WalletLecherEvent(this, market,
market.leechWallet()));
}
}
}
}
..and the method market.getWallet():
#Override
public Wallet getWallet() {
return this.wallet;
}
I think that the intention is to block all threads from getting old Wallets, thus wrongfully synchronized/ deprecated data - as long as this thread runs();
The code obtains the locks on the following objects:
this - Prevents multiple threads from calling run() on the same WalletLeecherWorker instance
this.market - Prevents the run() from proceeding if another thread has obtained a lock on it, which is a reasonable assumption considering that the market instance is probably shared
this.market.wallet - Same as previous
None of these are obviously unnecessary, except for the run() method being synchronized. It offers no protection beyond what the following synchronized block does. The code itself could be because of very fine grained locking being used, with this particular code needing to lock everything, whereas other code may lock only the wallet or the market and the wallet.
However this code can be error (and even deadlock) prone. If you lock the objects in the wrong order, you can get a deadlock. It's also not very readable as you see. It's also dubious to have a Thread as an instance variable of the class with a startThread() method. The code may not be broken, but it's certainly not very pretty.
The following code will work, but I slightly resent having to write the isRunning() method:
class Test {
private boolean running;
public void startX() {
synchronized(this) {
running = true
}
while (isRunning()) {
//do something
}
}
public synchronized void stopX() {
running = false;
}
private synchronized boolean isRunning() {
return running;
}
}
Can I synchronize reads of the running variable in the while (running){} in some other way, or do I have to write the isRunning() method? The same question applies to other control variables as well, eg
for (;running;) {}
or
if (running) {}
In all of these cases it seems as though you're forced into writing a pointless method to get the synchronization correct. Am I missing something?
if you are only resetting the value of running once to designate to stop, you might be able to use the volatile keyword.
However, if you need to start and stop many times, this won't work. This is because volatile fields "may miss an update"
Here's a link to explanation of when volatile works in cases like this link
here's the code sample from that link incase it goes dead:
public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
while (!pleaseStop) {
// do some stuff...
}
}
public void tellMeToStop() {
pleaseStop = true;
}
}
If you need to start and stop many times, then you need to either use one of the Java 5 concurrent lock objects or explicit synchronization
You could make the running field volatile. Making the field volatile puts the JVM on notice that it should make changes to that field visible to other threads.
The "miss an update" caveat is for cases where you want to read a value and update based on that value, which doesn't seem applicable here.
Multiple threads can write to this field, if all they're doing is setting a boolean flag then this won't be a problem.
Alternatively, if you are trying to cancel a thread, there's already an equivalent flag provided on Thread for this (and the visibility issue is taken care of). You can call interrupt on a thread, the code in the Runnable can query Thread.currentThread().isInterrupted() in order to tell whether it's been interrupted. This is preferable over using your own flag because the interruption will cause the thread to wake up if it is waiting or sleeping. With your own flag you have to wait until control reaches a place where the flag can be tested.
just to add up to other people's answer that suggested volatile .
Alternatively you could create a class for the checks.
I have made the variable to be static, so all threads will be pointing to same object.
class Runner{
boolean static running=true;
public static synchronized boolean getRunning(){
return running;
}
public static synchronized boolean setRunning(boolean r){
running=r;
}
}
NOTE:
if you don't require the global variable, then remove the static
I have a class that has the object "Card". This class keeps checking to see if the object is not null anymore. Only one other thread can update this object. Should I just do it like the code below? Use volatile?Syncronized? lock (which I dont know how to use really)? What do you recommend as easiest solution?
Class A{
public Card myCard = null;
public void keepCheck(){
while(myCard == null){
Thread.sleep(100)
}
//value updated
callAnotherMethod();
}
Another thread has following:
public void run(){
a.myCard = new Card(5);
}
What do you suggest?
You should use a proper wait event (see the Guarded Block tutorial), otherwise you run the risk of the "watching" thread seeing the reference before it sees completely initialized member fields of the Card. Also wait() will allow the thread to sleep instead of sucking up CPU in a tight while loop.
For example:
Class A {
private final Object cardMonitor = new Object();
private volatile Card myCard;
public void keepCheck () {
synchronized (cardMonitor) {
while (myCard == null) {
try {
cardMonitor.wait();
} catch (InterruptedException x) {
// either abort or ignore, your choice
}
}
}
callAnotherMethod();
}
public void run () {
synchronized (cardMonitor) {
myCard = new Card(5);
cardMonitor.notifyAll();
}
}
}
I made myCard private in the above example. I do recommend avoiding lots of public fields in a case like this, as the code could end up getting messy fast.
Also note that you do not need cardMonitor -- you could use the A itself, but having a separate monitor object lets you have finer control over synchronization.
Beware, with the above implementation, if run() is called while callAnotherMethod() is executing, it will change myCard which may break callAnotherMethod() (which you do not show). Moving callAnotherMethod() inside the synchronized block is one possible solution, but you have to decide what the appropriate strategy is there given your requirements.
The variable needs to be volatile when modifying from a different thread if you intend to poll for it, but a better solution is to use wait()/notify() or even a Semaphore to keep your other thread sleeping until myCard variable is initialized.
Looks like you have a classic producer/consumer case.
You can handle this case using wait()/notify() methods. See here for an example: How to use wait and notify in Java?
Or here, for more examples: http://www.programcreek.com/2009/02/notify-and-wait-example/
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.
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.