Should i use lock.lock(): in this method? - java

I wrote this method whose purpose is to give notice of the fact that a thread is leaving a
specific block of code
A thread stands for a car which is leaving a bridge so other cars can traverse it .
The bridge is accessible to a given number of cars (limited capacity) and it's one way only.
public void getout(int diection){
// release the lock
semaphore.release();
try{
lock.lock(); //access to shared data
if(direction == Car.NORTH)
nNordTraversing--; //decreasing traversing threads
else
nSudTraversing--;
bridgeCond.signal();
}finally{
lock.unlock();
}
}
My question is: should I use lock.lock(); or it's just nonsense?
thanks in advance

As we don't have the complete code (what is that semaphore ?), this answer is partly based on guess.
If your question is related to the increment and decrement operations, then you should know that those operation aren't, in fact, atomic.
So yes, if you have other threads accessing those variables, you need to protect them to ensure that no other thread can read them or worse try to do the same operation, as two parallel increments may result in only one effective.
But as locking has a cost, you may also encapsulate your variable in AtomicLong.

From the code snippet and requirement getout will not be called by simulatenous thread, only thread which is at the front of the queue, hence the method which is calling getout should be synchronized, as not all threads(cars) can be at the front of the queue.
I also think you are using semaphore as your guard lock in the calling method.
If in your implementation getout is being called by multiple methods then yes you need synchronization and your code is correct.

Well, I assume that nNordTraversing and nSudTraversing are shared data. Since ++ and -- are not atomic operations it is sensefull to lock them, before changing. Otherwise what could happen is the following:
you read the variable nNordTraversing (e.g. 7)
another Thread gets scheduled and completes its getout method, it changed the variable (e.g. 7 -- --> 6)
you are scheduled back, change the variable but on the old data you read (e.g. 7 --> 8)before the other thread changed it
the changes of the other thread got over written, the count is not consistent anymore (e.g. its 8 now, but should be 7)
This is called the lost update problem.

Related

Is it thread-safe to synchronize only on add to HashSet?

Imagine having a main thread which creates a HashSet and starts a lot of worker threads passing HashSet to them.
Just like in code below:
void main() {
final Set<String> set = new HashSet<>();
final ExecutorService threadExecutor =
Executors.newFixedThreadPool(10);
threadExecutor.submit(() -> doJob(set));
}
void doJob(final Set<String> pSet) {
// do some stuff
final String x = ... // doesn't matter how we received the value.
if (!pSet.contains(x)) {
synchronized (pSet) {
// double check to prevent multiple adds within different threads
if (!pSet.contains(x)) {
// do some exclusive work with x.
pSet.add(x);
}
}
}
// do some stuff
}
I'm wondering is it thread-safe to synchronize only on add method? Is there any possible issues if contains is not synchronized?
My intuition telling me this is fine, after leaving synchronized block changes made to set should be visible to all threads, but JMM could be counter-intuitive sometimes.
P.S. I don't think it's a duplicate of How to lock multiple resources in java multithreading
Even though answers to both could be similar, this question addresses more particular case.
I'm wondering is it thread-safe to synchronize only on the add method? Are there any possible issues if contains is not synchronized as well?
Short answers: No and Yes.
There are two ways of explaining this:
The intuitive explanation
Java synchronization (in its various forms) guards against a number of things, including:
Two threads updating shared state at the same time.
One thread trying to read state while another is updating it.
Threads seeing stale values because memory caches have not been written to main memory.
In your example, synchronizing on add is sufficient to ensure that two threads cannot update the HashSet simultaneously, and that both calls will be operating on the most recent HashSet state.
However, if contains is not synchronized as well, a contains call could happen simultaneously with an add call. This could lead to the contains call seeing an intermediate state of the HashSet, leading to an incorrect result, or worse. This can also happen if the calls are not simultaneous, due to changes not being flushed to main memory immediately and/or the reading thread not reading from main memory.
The Memory Model explanation
The JLS specifies the Java Memory Model which sets out the conditions that must be fulfilled by a multi-threaded application to guarantee that one thread sees the memory updates made by another. The model is expressed in mathematical language, and not easy to understand, but the gist is that visibility is guaranteed if and only if there is a chain of happens before relationships from the write to a subsequent read. If the write and read are in different threads, then synchronization between the threads is the primary source of these relationships. For example in
// thread one
synchronized (sharedLock) {
sharedVariable = 42;
}
// thread two
synchronized (sharedLock) {
other = sharedVariable;
}
Assuming that the thread one code is run before the thread two code, there is a happens before relationships between thread one releasing the lock and thread two acquiring it. With this and the "program order" relations, we can build a chain from the write of 42 to the assignment to other. This is sufficient to guarantee that other will be assigned 42 (or possibly a later value of the variable) and NOT any value in sharedVariable before 42 was written to it.
Without the synchronized block synchronizing on the same lock, the second thread could see a stale value of sharedVariable; i.e. some value written to it before 42 was assigned to it.
That code is thread safe for the the synchronized (pSet) { } part :
if (!pSet.contains(x)) {
synchronized (pSet) {
// Here you are sure to have the updated value of pSet
if (!pSet.contains(x)) {
// do some exclusive work with x.
pSet.add(x);
}
}
because inside the synchronized statement on the pSet object :
one and only one thread may be in this block.
and inside it, pSet has also its updated state guaranteed by the happens-before relationship with the synchronized keyword.
So whatever the value returned by the first if (!pSet.contains(x)) statement for a waiting thread, when this waited thread will wake up and enter in the synchronized statement, it will set the last updated value of pSet. So even if the same element was added by a previous thread, the second if (!pSet.contains(x)) would return false.
But this code is not thread safe for the first statement if (!pSet.contains(x)) that could be executed during a writing on the Set.
As a rule of thumb, a collection not designed to be thread safe should not be used to perform concurrently writing and reading operations because the internal state of the collection could be in a in-progress/inconsistent state for a reading operation that would occur meanwhile a writing operation.
While some no thread safe collection implementations accept such a usage in the facts, that is not guarantee at all that it will always be true.
So you should use a thread safe Set implementation to guarantee the whole thing thread safe.
For example with :
Set<String> pSet = ConcurrentHashMap.newKeySet();
That uses under the hood a ConcurrentHashMap, so no lock for reading and a minimal lock for writing (only on the entry to modify and not the whole structure).
No,
You don't know in what state the Hashset might be during add by another Thread. There might be fundamental changes ongoing, like splitting of buckets, so that contains may return false during the adding by another thread, even if the element would be there in a singlethreaded HashSet. In that case you would try to add an element a second time.
Even Worse Scenario: contains might get into an endless loop or throw an exception because of an temporary invalid state of the HashSet in the memory used by the two threads at the same time.

Can objects get lost if a LinkedList is add/remove fast by lots of threads?

sound like a silly question. I just started Java Concurrency.
I have a LinkedList that acts as a task queue and is accessed by multiple threads. They removeFirst() and execute it, other threads put more tasks (.add()). Tasks can have the thread put them back to the queue.
I notice that when there are a lot of tasks and they are put back to the queue a lot, the number of tasks I add to the queue initially are not what come out, 1, or sometimes 2 is missing.
I checked everything and I synchronized every critical section + notifyAll().
Already mark the LinkedList as 'volatile'.
Exact number is 384 tasks, each is put back 3072 times.
The problem doesn't occur if there is a small number of tasks & put back. Also if I System.out.println() all the steps then it doesn't happens anymore so I can't debug.
Could it be possible that LinkedList.add() is not fast enough so the threads somehow miss it?
Simplified code:
public void callByAllThreads() {
Task executedTask = null;
do
{
// access by multiple thread
synchronized(asyncQueue) {
executedTask = asyncQueue.poll();
if(executedTask == null) {
inProcessCount.incrementAndGet(); // mark that there is some processing going on
}
}
if(executedTask != null) {
executedTask.callMethod(); // subclass of task can override this method
synchronized(asyncQueue) {
inProcessCount.decrementAndGet();
asyncQueue.notifyAll();
}
}
}
while(executedTask != null);
}
The Task can override callMethod:
public void callMethodOverride() {
synchronized(getAsyncQueue()) {
getAsyncQueue().add(this);
getAsyncQueue().notifyAll();
}
}
From the docs for LinkedList:
Note that this implementation is not synchronized. If multiple threads access a linked list concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally.
i.e. you should synchronize access to the list. You say you are, but if you are seeing items get "lost" then you probably aren't synchronizing properly. Instead of trying to do that, you could use a framework class that does it for you ...
... If you are always removing the next available (first) item (effectively a producer/consumer implementation) then you could use a BlockingQueue implementation, This is guaranteed to be thread safe, and has the advantage of blocking the consumer until an item is available. An example is the ArrayBlockingQueue.
For non-blocking thread-safe queues you can look at ConcurrentLinkedQueue
Marking the list instance variable volatile has nothing to do with your list being synchronized for mutation methods like add or removeFirst. volatile is simply to do with ensuring that read/write for that instance variable is communicated correctly between, and ordered correctly within, threads. Note I said that variable, not the contents of that variable (see the Java Tutorials > Atomic Access)
LinkedList is definitely not thread safe; you cannot use it safely with multiple threads. It's not a question of "fast enough," it's a question of changes made by one thread being visible to other threads. Marking it volatile doesn't help; that only affects references to the LinkedList being changed, not changes to the contents of the LinkedList.
Consider ConcurrentLinkedQueue or ConcurrentLinkedDeque.
LinkedList is not thread safe, so yes, multiple threads accessing it simultaneously will lead to problems. Synchronizing critical sections can solve this, but as you are still having problems you probably made a mistake somewhere. Try wrapping it in a Collections.synchronizedList() to synchronize all method calls.
Linked list is not thread safe , you can use ConcurrentLinkedQueue if it fits your need,which seems possibly can.
As documentation says
An unbounded thread-safe queue based on linked nodes. This queue
orders elements FIFO (first-in-first-out). The head of the queue is
that element that has been on the queue the longest time. The tail of
the queue is that element that has been on the queue the shortest
time. New elements are inserted at the tail of the queue, and the
queue retrieval operations obtain elements at the head of the queue. A
ConcurrentLinkedQueue is an appropriate choice when many threads will
share access to a common collection. This queue does not permit null
elements.
You increment your inProcessCount when executedTask == null which is obviously the opposite of what you want to do. So it’s no wonder that it will have inconsistent values.
But there are other issues as well. You call notifyAll() at several places but as long as there is no one calling wait() that has no use.
Note further that if you access an integer variable consistently from inside synchronized blocks only throughout the code, there is no need to make it an AtomicInteger. On the other hand, if you use it, e.g. because it will be accessed at other places without additional synchronization, you can move the code updating the AtomicInteger outside the synchronized block.
Also, a method which calls a method like getAsyncQueue() three times looks suspicious to a reader. Just call it once and remember the result in a local variable, then everone can be confident that it is the same reference on all three uses. Generally, you have to ensure that all code is using the same list, hence the appropriate modifier for the variable holding it is final, not volatile.

mutual exclusion using thread of java

I have this code , It is mutual exclusion algorithm
turn = 0 // shared control variable
while (turn != i);
// CS
turn = (turn + 1) % n;
I know how thread works but really I'm little weak in using thread in java so please any suggestion to help me to understand how to convert it in real code using thread of java
sorry for my bad english
Mutual exclusion is typically achieved, in the simplest form, by marking a method as synchronized. By marking an object's method as synchronized, only one thread can ever execute that object's method at a time. The object owning the method is the monitor.
Additionally, you can define a synchronized block in the code itself, passing it the object to act as the monitor.
I believe you could achieve the same thing in a simpler fashion, by defining a Runnable object which has the logic you want done. Where you want the mutual exclusion, define a synchronized method.
Then that Runnable instance can be passed to as many Threads you need. As they all reference the same Runnable, calls into the synchronized method will be mutually exclusive.
This is not the only way, but it should be what you're after. Hope this helps.
this code is not mutually exclusive, consider this execution-
thread 0 enters the code and CS and then increments turn to 1 in the last line.
thread 1 enters the CS as turn equals 1,and stays
now thread 0 goes back to the first line and sets turn to 0 and then enters the CS together with thread 1

Synchronizing in a for each loop still throws ConcurrentModificationExceptions

I'm trying to iterate through a loop on one thread, like so:
for (UnitTask task : chain) {
g.drawLine((int) task.getLocation().getX(), (int) task.getLocation().getY(), (int) currentPos.getX(), (int) currentPos.getY());
g.fillOval((int) task.getLocation().getX() - 2, (int) task.getLocation().getY() - 2, 5, 5);
currentPos = task.getLocation();
}
However, I have another thread (the Swing event thread) which can add to this object. Hence, ConcurrentModificationException. I tried obtaining a lock by surrounding the code with synchronized (chain) { ... }, but I still get the errors.
As a bit of a Java synchronization newbie, I'm a little confused as to why. I would expect this to make the loop thread-safe, but evidently, it is not.
Interestingly, chain is an instance of a custom class, but it is only a thin wrapper around a LinkedList. The list itself is private, and there's no way for an external class to retrive it directly (there are methods to explicitly add/remove objects), so I wouldn't expect this to affect the outcome.
The meaning of
synchronized (c) {
... code that uses c ...
}
is
wait for c to be unlocked
lock c
execute the body
unlock c
So if you synchronize in your thread, then your thread will wait for c to be unlocked and then dive in.
Now, if you do not synchronize the code on the other thread that modifies c, that code is going to just go ahead and modify c without waiting for a lock. Synchronizing a block in one thread does not make another thread wait for a lock. If the other thread has a line such as
c.add(someOtherTask)
that is not in a synchronized block, then it's going to do the add no matter what. This is the cause of your exception. It is also the reason why you saw the exception even though you put the code in your thread in a synchronized block: your code was "playing by the rules" but the other thread couldn't have cared less.
Be careful about synchronizing long-running code though. You are better off, as Stephen C says, to use a concurrent collection type.
Synchronization will not necessarily help.
Basically the problem is that you are using a collection type that does not allow the collection to be modified while an iteration is in progress (except via the iterator's remove method ... if supported). This is not a threading / synchronization issue per se. (And if you try to solve it simply by synchronization, you may introduce another problem.)
If you want to be able to iterate and modify at the same time, you will need to use a different collection type such as ConcurrentLinkedDeque instead of LinkedList.
If the iteration and writing are happening on separate threads, then shouldn't synchronizing block the writing until the iteration is finished? Or am I missing something?
The problem will be in how you have implemented the synchronization:
If you are not explicitly doing some kind synchronization in your LinkedList version, then no synchronization is done for you.
If you use a synchronization wrapper created by one of the Collections.synchronizedXxx methods, then the javadocs for those methods clearly state that an Iterator object returned by the wrapper's iterator() method IS NOT synchronized.
If you are doing the synchronization by hand, then you have to make sure that everything is synchronizing on the same mutex. And that lock has to be held on that mutex for the duration of the iteration ... not just for the call the iterator().
And note that if you hold a lock for a long time (e.g. while you are iterating a long list), this can potentially block other threads that need to update the list for a long time. That kind of thing can be a concurrency bottleneck that can (in the worst case) reduce your system's performance to the speed of a single processor.
The ConcurrentXxx classes typically avoid this by relaxing the consistency guarantees for the sequences produced by the iterators. For instance, you may not see elements that were added to the collection after you started the iteration.

Multithreaded access and variable cache of threads

I could find the answer if I read a complete chapter/book about multithreading, but I'd like a quicker answer. (I know this stackoverflow question is similar, but not sufficiently.)
Assume there is this class:
public class TestClass {
private int someValue;
public int getSomeValue() { return someValue; }
public void setSomeValue(int value) { someValue = value; }
}
There are two threads (A and B) that access the instance of this class. Consider the following sequence:
A: getSomeValue()
B: setSomeValue()
A: getSomeValue()
If I'm right, someValue must be volatile, otherwise the 3rd step might not return the up-to-date value (because A may have a cached value). Is this correct?
Second scenario:
B: setSomeValue()
A: getSomeValue()
In this case, A will always get the correct value, because this is its first access so he can't have a cached value yet. Is this right?
If a class is accessed only in the second way, there is no need for volatile/synchronization, or is it?
Note that this example was simplified, and actually I'm wondering about particular member variables and methods in a complex class, and not about whole classes (i.e. which variables should be volatile or have synced access). The main point is: if more threads access certain data, is synchronized access needed by all means, or does it depend on the way (e.g. order) they access it?
After reading the comments, I try to present the source of my confusion with another example:
From UI thread: threadA.start()
threadA calls getSomeValue(), and informs the UI thread
UI thread gets the message (in its message queue), so it calls: threadB.start()
threadB calls setSomeValue(), and informs the UI thread
UI thread gets the message, and informs threadA (in some way, e.g. message queue)
threadA calls getSomeValue()
This is a totally synchronized structure, but why does this imply that threadA will get the most up-to-date value in step 6? (if someValue is not volatile, or not put into a monitor when accessed from anywhere)
If two threads are calling the same methods, you can't make any guarantees about the order that said methods are called. Consequently, your original premise, which depends on calling order, is invalid.
It's not about the order in which the methods are called; it's about synchronization. It's about using some mechanism to make one thread wait while the other fully completes its write operation. Once you've made the decision to have more than one thread, you must provide that synchronization mechanism to avoid data corruption.
As we all know, that its the crucial state of the data that we need to protect, and the atomic statements which govern the crucial state of the data must be Synchronized.
I had this example, where is used volatile, and then i used 2 threads which used to increment the value of a counter by 1 each time till 10000. So it must be a total of 20000. but to my surprise it didnt happened always.
Then i used synchronized keyword to make it work.
Synchronization makes sure that when a thread is accessing the synchronized method, no other thread is allowed to access this or any other synchronized method of that object, making sure that data corruption is not done.
Thread-Safe class means that it will maintain its correctness in the presence of the scheduling and interleaving of the underlining Runtime environment, without any thread-safe mechanism from the Client side, which access that class.
Let's look at the book.
A field may be declared volatile, in which case the Java memory model (§17) ensures that all threads see a consistent value for the variable.
So volatile is a guarantee that the declared variable won't be copied into thread local storage, which is otherwise allowed. It's further explained that this is an intentional alternative to locking for very simple kinds of synchronized access to shared storage.
Also see this earlier article, which explains that int access is necessarily atomic (but not double or long).
These together mean that if your int field is declared volatile then no locks are necessary to guarantee atomicity: you will always see a value that was last written to the memory location, not some confused value resulting from a half-complete write (as is possible with double or long).
However you seem to imply that your getters and setters themselves are atomic. This is not guaranteed. The JVM can interrupt execution at intermediate points of during the call or return sequence. In this example, this has no consequences. But if the calls had side effects, e.g. setSomeValue(++val), then you would have a different story.
The issue is that java is simply a specification. There are many JVM implementations and examples of physical operating environments. On any given combination an an action may be safe or unsafe. For instance On single processor systems the volatile keyword in your example is probably completely unnecessary. Since the writers of the memory and language specifications can't reasonably account for possible sets of operating conditions, they choose to white-list certain patterns that are guaranteed to work on all compliant implementations. Adhering to to these guidelines ensures both that your code will work on your target system and that it will be reasonably portable.
In this case "caching" typically refers to activity that is going on at the hardware level. There are certain events that occur in java that cause cores on a multi processor systems to "Synchronize" their caches. Accesses to volatile variables are an example of this, synchronized blocks are another. Imagine a scenario where these two threads X and Y are scheduled to run on different processors.
X starts and is scheduled on proc 1
y starts and is scheduled on proc 2
.. now you have two threads executing simultaneously
to speed things up the processors check local caches
before going to main memory because its expensive.
x calls setSomeValue('x-value') //assuming proc 1's cache is empty the cache is set
//this value is dropped on the bus to be flushed
//to main memory
//now all get's will retrieve from cache instead
//of engaging the memory bus to go to main memory
y calls setSomeValue('y-value') //same thing happens for proc 2
//Now in this situation depending on to order in which things are scheduled and
//what thread you are calling from calls to getSomeValue() may return 'x-value' or
//'y-value. The results are completely unpredictable.
The point is that volatile(on compliant implementations) ensures that ordered writes will always be flushed to main memory and that other processor's caches will be flagged as 'dirty' before the next access regardless of the thread from which that access occurs.
disclaimer: volatile DOES NOT LOCK. This is important especially in the following case:
volatile int counter;
public incrementSomeValue(){
counter++; // Bad thread juju - this is at least three instructions
// read - increment - write
// there is no guarantee that this operation is atomic
}
this could be relevant to your question if your intent is that setSomeValue must always be called before getSomeValue
If the intent is that getSomeValue() must always reflect the most recent call to setSomeValue() then this is a good place for the use of the volatile keyword. Just remember that without it there is no guarantee that getSomeValue() will reflect to most recent call to setSomeValue() even if setSomeValue() was scheduled first.
If I'm right, someValue must be volatile, otherwise the 3rd step might not return the up-to-date value (because A may have a cached
value). Is this correct?
If thread B calls setSomeValue(), you need some sort of synchronization to ensure that thread A can read that value. volatile won't accomplish this on its own, and neither will making the methods synchronized. The code that does this is ultimately whatever synchronization code you added that made sure that A: getSomeValue() happens after B: setSomeValue(). If, as you suggest, you used a message queue to synchronize threads, this happens because the memory changes made by thread A became visible to thread B once thread B acquired the lock on your message queue.
If a class is accessed only in the second way, there is no need for
volatile/synchronization, or is it?
If you are really doing your own synchronization then it doesn't sound like you care whether these classes are thread-safe. Be sure that you aren't accessing them from more than one thread at the same time though; otherwise, any methods that aren't atomic (assiging an int is) may lead to you to be in an unpredictable state. One common pattern is to put the shared state into an immutable object so that you are sure that the receiving thread isn't calling any setters.
If you do have a class that you want to be updated and read from multiple threads, I'd probably do the simplest thing to start, which is often to synchronize all public methods. If you really believe this to be a bottleneck, you could look into some of the more complex locking mechanisms in Java.
So what does volatile guarantee?
For the exact semantics, you might have to go read tutorials, but one way to summarize it is that 1) any memory changes made by the last thread to access the volatile will be visible to the current thread accessing the volatile, and 2) that accessing the volatile is atomic (it won't be a partially constructed object, or a partially assigned double or long).
Synchronized blocks have analogous properties: 1) any memory changes made by the last thread to access to the lock will be visible to this thread, and 2) the changes made within the block are performed atomically with respect to other synchronized blocks
(1) means any memory changes, not just changes to the volatile (we're talking post JDK 1.5) or within the synchronized block. This is what people mean when they refer to ordering, and this is accomplished in different ways on different chip architectures, often by using memory barriers.
Also, in the case of synchronous blocks (2) only guarantees that you won't see inconsistent values if you are within another block synchronized on the same lock. It's usually a good idea to synchronize all access to shared variables, unless you really know what you are doing.

Categories