What could be the understanding of the following?
I have gone through this post at SO but still at a loss to assemble it.
code1:
synchronized(this){
// some code
}
code2:
Object lock = new Object();
synchronized(lock){
// some code
}
Any tutorial, or some links to explain synchronized like they explain it to a child?
Basically there is a "lock" associated with every object in Java.
When a thread reaches a call to synchronized(something), it has to acquire the lock of something before continuing. If you want to allow only one thread at a time to modify the state of an object, the most obvious thing is to synchronize on the lock of that object. If different methods are allowed to be called in parallel, you need different locks for that.
If you write synchronized(this), or simply synchronized, the thread must acquire the lock associated with the current object (of which method is called).
Note that since Java 5.0 there concurrent package provides proper locks which can be used instead of synchronization.
One thing not mentioned in the otherwise excellent answers already given is that difference between code1 and code2. In code1, the synchronization is on the instance of the object in which the code is found, and in code2, it's on the specific lock object within the object.
If there's only the two synchronized blocks in the enclosing class, there's no functional difference between the two, but consider this:
class CodeOneClass {
...
synchronized(this) { // or merely "synchronized" - it defaults to this
first protected code block
}
...
synchronized(this) {
second protected code block
}
...
}
class CodeTwoClass {
...
Object lock1 = new Object();
synchronized(lock1) {
first protected code block
}
...
Object lock2 = new Object();
synchronized(lock2) {
second protected code block
}
...
}
If two threads are trying to use the same instance of CodeOneClass, only one of them can be in either of the two protected code blocks at the same time.
But with the second idiom, you have the flexibility to say that it's safe for one thread to be in the first protected block, and another to be in the other. Note that if the locks were the same (both synchronizing on the same lock object), the behavior would be as the first.
There are other differences. Some writers are beginning to point out issues with synchronized(this) - I would point you to another post here on SO:
Avoid synchronized(this) in Java?
I highly recommend reading it, and the three posts it links to.
Putting code within a synchronized block essentially means, "Once this code starts running, other code that needs to use this object cannot run at the same time."
So, if Thread #2 is executing code in your code2 block, when it comes to the synchronized(lock) code it has to effectively look around at all the other threads to make sure nobody else is running "synchronized" code with the lock object at the moment. Thread #1 is certainly running some code at the same time, but it might be completely unrelated code. If so, it's safe for Thread #2 to start running your "some code" stuff.
Meanwhile, if Thread #1 gets to the synchronized(this) block, it too has to pause and see if any other threads are using this. If this is the same object as lock, we have a problem. We were told that only one thread can possibly use that object (in a synchronized block) at the same time. Yet Thread #2 is already using it. Thread #1 will just have to wait... and wait... and wait... until eventually Thread #2 finishes. Then we can proceed.
The end result is that only one synchronized block can run at a time (with a particular object, of course).
Suppose you have an Account object which has a method:
void debit(long debitAmount, Account beneficiary) throws InsufficientFundsException
{
if (accountBalance >= debitAmount) {
accountBalance -= debitAmount;
beneficiary.credit(debitAmount);
}
else {
throw new InsufficientFundsException();
}
}
Now suppose you have an account with a balance of 100 euros, and you get two attempts to debit it by 70 euros. If the two debits occur at the same time, you can get a race condition like this:
First debit checks account balance: 100 >= 70, so succeeds
Second debit checks account balance: 100 >= 70, so succeeds
First debit executes; account balance becomes 30
Second debit executes; account balance becomes -40. Shouldn't be allowed
We can prevent this dire state of affairs by synchronizing on the Account object's lock:
void debit(long debitAmount, Account beneficiary) throws InsufficientFundsException
{
synchronized (this) {
if (accountBalance >= debitAmount) {
accountBalance -= debitAmount;
beneficiary.credit(debitAmount);
}
else {
throw new InsufficientFundsException();
}
}
}
This makes sure that the test on the account balance and the debit can't be interrupted by another test on the account balance.
The Sun Java tutorial is a good place to start for information on concurrency and locking.
Related
I hope I can understandably describe the situation.
I want to start some amount of threads and all of them will execute one synchronized method. Consider first thread checks value of a variable in this method then the lock will be released after check.Then the second thread calls the same function. But first thread will then (after some ms) modify this variable which is in another class but second thread will (maybe) check the variable before the first changed it. How can I force the second thread to wait (without sleep) till the first has finished and changed the variable before the second checks the value? Can the first send some signal like "variable changed, u can check it now"?
Now I try to write this in code: threads started all all do this run:
abstract class Animal {
protected House house;
abstract boolean eating();
#Override
public void run() {
try {
while(!Thread.interrupted()) {
if(eating()) {
goEat();//here house.eatingRoom.count will be changed
Thread.sleep(1000);
goback();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
All of them access this method:
class Cat extends Animal {
#Override
synchronized boolean eating() {
if (house.eatingRoom.count == 0)
return true;//first thread release lock and 2 thread access it but the value is not changed yet
else
return false;
}
}
And:
class EatingRoom {
final Set<Animal> count = new HashSet<>();
synchronized void add(Cat c) {
count.add(c);
}
}
to complete:
public class House extends Thread {
final EatingRoom eatingRoom = new EatingRoom();
//start all threads here so run in Animal class is executed..
}
The problem you are describing sounds like you could benefit from the Java synchronisation primitives like Object.wait and Object.notify.
A thread that owns the lock/monitor of a given object (such as by using the synchronized keyword) can call wait instead of looping and sleeping in a busy/wait pattern like you have in while(!Thread.interrupted()) which may waste many CPU cycles.
Once the thread enters the wait state it will release the lock it holds, which allows another thread to acquire that same lock and potentially change some state before then notifying one or more waiting threads via notify/notifyAll.
Note that one must be careful to ensure locks are acquired and released in the same order to help avoid deadlock scenarios when more than one lock is involved. Consider also using timeouts when waiting to ensure that your thread doesn't wait indefinitely for a condition that might never arise. If there are many waiting threads when you call notify be aware that you might not know which thread will be scheduled but you can set a fairness policy to help influence this.
Depending on the structure of your code you may be able to avoid some of the lower level primitives like synchronised blocks by using some higher level APIs such as https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/Lock.html or keywords like volatile for variables that contain shared mutable state (like a condition you want to wait for to ensure the result of a write is observed on a subsequent read in a "happens before" relationship.
Given that there's only one lock for each instance of a class, then why doesn't Java just allow us to do this:
void method() {
synchronized {
// do something
}
// do other things
}
instead of this:
void method() {
synchronized (lock) {
// do something
}
// do other things
}
What's the purpose of specifying a lock? Does it make a difference if I choose one object as a lock over the other? Or could I just choose any random object?
EDIT:
It turned out that my comprehension of synchronized methods is wrong at the fundamental level.
I thought different synchronized methods or blocks are entirely independent of each other regardless of locks. Rather, all synchronized methods or blocks with the same lock can be accessed only by one thread, even if such synchronized methods/blocks are from different classes (the documentation should have emphasized this more: ALL synced methods/blocks, regardless of location, all that matters is the lock).
Given that there's only one lock for each instance of a class, then why doesn't Java just allow us to do this:
void method() {
synchronized {
// do something
}
// do other things
}
Although an intrinsic lock is provided with each instance,
that's not necessarily the "obvious" lock to use.
You're perhaps right that they could have provided synchronized { ... } as a shorthand for synchronized (this) { ... }.
I don't know why they didn't, but I never missed it.
But concurrent programming is tricky,
so making the lock object an explicit required parameter may make things clearer to readers, which is a good thing, as #ajb pointed out in a comment.
In any case, I don't think syntax is your main question, so let's move on.
What's the purpose of specifying a lock?
Uhm, the lock is perhaps the single most important thing in the synchronization mechanism. The key point in synchronization is that only one thread can hold the same lock. Two threads holding different locks are not synchronized. So knowing what is the lock guarding the synchronization is crucial.
Does it make a difference if I choose one object as a lock over the other?
I hope the previous section makes it clear that yes, you have to choose the object carefully. It has to be an object visible by all threads involved,
it has to be not null, and it has to be something that won't get reassigned during the period of synchronization.
Or could I just choose any random object?
Certainly not. See the previous section.
To understand concurrency in Java, I recommend the book Java Concurrency in Practice by one of the authors of the API, or Oracle's tutorials on the subject.
It's so you can lock on something completely different than this.
Remember how Vector is "thread-safe?" It's not quite that simple; each call is, but code like this isn't because it could have been updated between getting the size of the vector and getting the element:
for (int i = 0; i < vector.size(); ++i) System.out.println(vector.get(i));
Since Vector, along with Collections.synchronized*, is synchronized with the older synchronized keyword, you can make that above code thread-safe by enclosing it all within a lock:
synchronized (vector) {
for (int i = 0; i < vector.size(); ++i) System.out.println(vector.get(i));
}
This could be in a method that isn't thread-safe, isn't synchronized, or uses ReentrantLock; locking the vector is separate from locking this.
It most certainly makes a difference what object you use as a lock. If you say
void method() {
synchronized (x) {
// do something
}
// do other things
}
Now, if one thread is executing the block and another tries to enter the block, if x is the same for both of them, then the second thread will have to wait. But if x is different, the second thread can execute the block at the same time. So, for example, if method is an instance method and you say
void method() {
synchronized (this) {
// do something
}
// do other things
}
Now two threads running the method using the same object can't execute the block simultaneously, but two threads can still run the method on different objects without blocking each other. This is what you'd want when you want to prevent simultaneous access to the instance variables in that object, but you don't have anything else you need to protect. It's not a problem if two threads are accessing variables in two different objects.
But say the block of code is accessing a common resource, and you want to make sure all other threads are locked out of accessing that resource. For example, you're accessing a database, and the block does a series of updates and you want to make sure they're done atomically, i.e. no other code should access the database while you're in between two updates. Now synchronized (this) isn't good enough, because you could have the method running for two different objects but accessing the same database. In this case, you'd need a lock that is the same for all objects that might access the same database. Here, making the database object itself the lock would work. Now no two threads can use method to enter this block at the same time, if they're working with the same database, even if the objects are different.
if you have multiple objects b1/b2 needs to update concurrency
class A {
private B b1, b2;
}
if you have only one lock say class A itself
synchronized (this) { ... }
then assume there are two threads are updating b1 and b2 in the same time, they will play one by one because synchronized (this)
but if you have two locks for b1 and b2
private Object lock1 = new Object, lock2 = new Object;
the two threads i've mentioned will play concurrently because synchronized (lock1) not affect synchronized (lock2).sometimes means better performance.
In synchronized (lock).., lock can be an object level lock or it can be class level lock.
Example1 Class Level Lock:
private static Object lock=new Object();
synchronized (lock){
//do Something
}
Example2 Object Level Lock:
private Object lock=new Object();
synchronized (lock){
//do Something
}
I am new to multi-threading in java, and I have a question some might find trivial.
I have to debug a third party piece of code and I need some basic information, to know where to look for the problem because the code is very large.
When the following code runs:
public void method()
{
long startTime = System.currentTimeMillis();
synchronized (obj)
{
log( "time:" + System.currentTimeMillis() - startTime + " ms" );
...
}
}
I get:
11:13:12 - time: 3816 ms
...
11:14:14 - time: 0 ms
Why is taking so long (3816 ms) to get the lock for the object?
Where should I look? For example, I would imagine a possible answer would be to look for code which acquires the lock for "obj" i.e. block such as:
synchronized (obj) { ... }
Or is it possible that any modification at the object "obj" without "synchronized" can also lock the object?
If it takes a thread that long to obtain a lock, it's because someone else is currently holding it.
You should look for two things:
Code blocks which synchronize on the same object or on other references to it (known as synchronized statements) :
synchronized (obj) {
...
}
Synchronized methods within the object itself.
Say obj is of type MyObject, then you should look for methods such as these:
public class MyObject{
public synchronized void myMethod() {
...
}
}
Because they are essentially the same as
public class MyObject{
public void myMethod() {
synchronized (this) {
...
}
}
}
So if a thread is executing obj.myMethod(), threads that want to enter a synchronized (obj) block will have to wait, as they all lock on the same object. This, by the way, is the reason why I strongly recommend never using the synchronized method syntax, and always locking over a private (or protected) class member.
If another thread is currently executing code within such a block, the current thread will be locked out until the other thread finishes.
You can use jvisualvm's Threads tab or Jstack to take snapshots of the current execution state of all threads and the locks they're holding. If you're on android, see this answer on how to get a thread dump on there.
The jstack utility that is part of the jdk can help with this. The -l (long listing) option will print all of the locks held by various threads. If you can catch your program in the midst of the issue then you can find the other thread that is holding the lock. You do this by finding your thread, seeing what condition object it is waiting on, then searching the rest of the stack traces for that condition object.
This article has more detailed information about how to look at the thread dump.
You need to check the following:
Are there any method/block in your obj class, which is synchronized on this. If yes then there must be multiple threads where one is your above code, while other might be using the methods of same obj.
Where all you are sharing obj? If it's shared by multiple classes, then check out who locks on same obj.
I can't seem to find any example of what I want to ask:
Let's say I have in class Account
public void transferMoney(Account fromAccount, Account toAccount, DollarAmount amountToTransfer) {
if (fromAccount.hasSufficientBalance(amountToTransfer) {
fromAccount.debit(amountToTransfer);
toAccount.credit(amountToTransfer);
}
}
this may cause a race condition when used in an overriden run method, and I have this code in Main:
Account acc1 = new Account(..);
Account acc2 = new Account(..);
Thread t1 = new Thread(new Transfer(..from acc1 to acc2..));
Thread t2 = new Thread(new Transfer(..from acc2 to acc1..));
synchronized (acc1) {
t1.start();
}
synchronized (acc2) {
t2.start()
}
Synchronizing these two instances of Account acc1 and acc2 does not prevent the Race Condition, but I don't know why or what synchronizing does exactly in this case!
I couldn't find any example about this kind of synchronize.
synchronized only has an effect if a thread tries to enter a synchronized block while another thread currently is in a synchronized block referring to the same object. Here, only your main thread synchronizes on acc1 and acc2, hence no synchronization will actually take place.
A better design for your case would be to aggregate hasSufficientBalance and debit into a single method, which is synchronized (which is equivalent to the whole method body being enclosed in a synchronized(this) block). This synchronized serves to protect the internal state of the class. Therefore, you will also want to mark the credit method as synchronized.
public synchronized boolean debitIfHasSufficientBalance(DollarAmount amount) {
if (hasSufficientBalance(amount)) {
debit(amount);
return true;
}
return false;
}
Your transferMoney could then be rewritten as following, without any explicit synchronization:
public void transferMoney(Account fromAccount, Account toAccount, DollarAmount amountToTransfer) {
if (fromAccount.debitIfHasSufficientBalance(amountToTransfer)) {
toAccount.credit(amountToTransfer);
}
}
When you say:
synchronized (acc1) {
t1.start();
}
that causes the current thread to try to acquire the lock on the object acc1, then, once it has that lock, the current thread starts the thread t1. At that point t1's run method gets called in a new thread, and that new thread can do whatever it wants, it's not subject to any locking. You don't lock a thread as such, threads work by acquiring locks that give them access to shared data. When a thread tries to enter a synchronized block that another thread has acquired the lock for, it has to block until it can get the lock.
Synchronizing doesn't do anything unless the different threads are locking on something that's shared. Here one thread locks on one object and the other thread locks on a different object, so there is no effect.
It would seem like you'd want a lock on acc1 and on acc2:
synchronized (acc1) {
synchronized (acc2) {
... now do the transfer
}
}
This creates problems because you have to get the locks in the same order or risk deadlock.
Also it depends on the instances of acc1 and acc2 being shared among the different threads; if different threads instantiate their own copies (for instance with Hibernate each thread would have its own session and would make its own copy of any persistent entities) this won't work.
In real life you wouldn't do this; for things like account transfers you'd probably use database locking or transactions for this, where the database is the shared resource that limits access. Toy examples can cause confusion sometimes because people get distracted picking apart the toy example. A real-life situation where you would see synchronization is on collections (lists, maps, queues, etc.) that need to be accessed by multiple threads.
Well, you probably don't want Account objects to be in charge of transferring money among themselves. Instead I would recommend implementing some sort of controller object, which facilitates the transfers.
To ensure your controller object can only have a single instance, a good way to go about this is to make it an Enum, which brings along the synchronization stuff "for free" as Josh Bloch would say.
http://www.informit.com/articles/article.aspx?p=1216151&seqNum=3
http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-with-examples
http://javarevisited.blogspot.com/2012/07/why-enum-singleton-are-better-in-java.html
Remember, with an Enum, there is only ever one that exists in your program, so if you call it from two different threads, one will be blocked until the Enum is released by the other caller. This happens automagically with Enum objects.
public Enum AccountController {
MyBankProgram,
;
/**
* Transfers DollarAmount from Account a to Account b.
*/
public void transferFunds(final Account a, final Account b, DollarAmount d) {
// do stuff here
a.subtract(d);
b.add(d);
}
}
This would be used as:
AccountController.MyBankProgram.transferFunds(accountA, accountB, new DollarAmount("45.00"));
then your Account objects would only need publically exposed methods of:
public void add(final DollarAmount n);
public void subtract(final DollarAmount n);
And I would recommend these go through your controller object and not be called from anywhere else, you don't want random pieces of code adding or removing funds!
I do not really understand what do these synchronized locks exactly lock?
They don't lock anything. "Lock" is a very misleading name in this context.
The synchronized keyword does one thing, and one thing only: It prevents two or more threads from synchronizing on the same object at the same time.
See #misberner 's answer for a good solution to your problem.
Works except for when I free the crawler:
public void setCrawlerFree(WebCrawler w)
{
synchronized(myFreeCrawlers)
{
synchronized(numToGo)
{
myFreeCrawlers.add(w);
myFreeCrawlers.notifyAll();
numToGo--;
numToGo.notify();
}
}
}
When the crawler is done, I can add it back on the list. I also want to subtract 1 from the number of things I still need to do. I have one main thread waiting until numToGo is at 0. I'm getting an IllegalMonitorStateException on numToGo.notify() but since its inside of the synchronization block, doesn't that mean I own it?
Consider rewriting it to ExecutorService.
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize, keepAliveTime, timeUnit,
new LinkedBlockingQueue<Runnable>());
executor.submit(new Callable<...>() { ... });
It would greatly simplify your code and eliminate thread synchronization issues.
So I thought I needed to call wait and
notify on the object that all the
threads have in common, but that's not
correct either.
Yes, it is. But:
public class IllegalMonitorStateException
extends RuntimeException
Thrown to indicate that a thread has
attempted to wait on an object's
monitor or to notify other threads
waiting on an object's monitor without
owning the specified monitor.
You need to synchronize on an object before calling wait() or notify() on it.
Is your numToGo field is a primitive type which is being wrapped ? (int to Integer, long to Long, etc). Remember these wrappers are immutable and will cause you to have different object every time the boxing/unboxing happens. It's always recommended to use final objects when synchronization is needed.
Instead of using and integer create your own object to maintain the value and synchronization.
class Counter {
private int value ;
private final Object lock = new Object() ;
public ExecutionStatus() { }
public void increment() {
synchronized(lock) {
value ++ ;
}
}
public void decrease() {
synchronized(lock) {
value-- ;
}
}
// Read dirty
public int count() {
return value ;
}
public int safeCount() {
synchronize(lock) {
return count() ;
}
}
}
Never the less, you can add the line private final Object lock = new Object() to your current code and use that to control the synchronization of the numToGo variable.
Hope this helps.
you are synchronising on a non-final member variable. Your sync(numToGo) syncs on some value of numToGo and then you change the reference: numToGo--. You now have a different instance on which you call notify, hence the exception.
Some good posts there, there are plenty of alternatives but I imagine this is some kind of academic exercise? As people have pointed out, you'd probably wouldn't use wait/notify/notifyAll when there are more modern alternatives that makes things easier. The wait/notify thing though is interesting and is well worth understanding as a basis for concurrency work.
I'm assuming this is some kind of consumer/producer thing? One thread is trapping a crawler, the other setting it free? If that's the case, you might want to wait for the trap to have occupants before setting free? it might look something like this...
private final List<Object> trap = new ArrayList<Object>();
public class BugCatcher {
public void trapCrawler(Object crawler) {
synchronized (trap) {
trap.add(crawler);
System.out.println("caught bug number " + trap.size() + "!");
trap.notifyAll();
}
}
}
public class Hippy {
public void setCrawlerFree(Object crawler) throws InterruptedException {
synchronized (trap) {
trap.wait();
trap.clear();
System.out.println("set bugs free! time to hug a tree");
}
}
}
If the BugCatcher can catch bugs quicker than the hippy releases them, the hippy waits for the trap to have something in it before attempting to release the bugs (hence the wait call).
If you leave out the wait/notify part, things will rely just on the synchronized keyword, only one thread will access the trap at a time and its a race as to which gets there first (the hippy might try an empty an already empty trap).
In order to co-ordinate the wait and notify, the VM will use an object monitor. A thread acquires the object's monitor when it enters a synchronized block. An object has just a single monitor which acts as a mutually exclusivity lock (mutex). If you try and wait or notify without first getting the object's monitor (without executing wait or notify within a synchronized block), the VM can't set things up and so throws the IllegalMonitorException. It's saying "I can't allow this because if, for example, I wait, when will I know that I can progress when somebody calls notify? what/who are they notifying?". It uses the monitor to coordinate and so forces you to acquire the monitor.
So, the error you get is because numToGo isn't syncrhonised in the other thread (as Michael said previously).
I can't quite see why you need the numToGo, if it is producer/consumer, do you want to stop after a certain number? After the bug catcher catches 10 bugs and the hippy releases 10? Doesn't sound like that's what you're trying to do (as they could both have unrelated internal counters), so I'm not sure what you trying to do there. It'd be good to outline what you're trying to do in case I've gone off on completely the wrong tangent!