I'm building a simple program to use in multi processes (Threads).
My question is more to understand - when I have to use a reserved word synchronized?
Do I need to use this word in any method that affects the bone variables?
I know I can put it on any method that is not static, but I want to understand more.
thank you!
here is the code:
public class Container {
// *** data members ***
public static final int INIT_SIZE=10; // the first (init) size of the set.
public static final int RESCALE=10; // the re-scale factor of this set.
private int _sp=0;
public Object[] _data;
/************ Constructors ************/
public Container(){
_sp=0;
_data = new Object[INIT_SIZE];
}
public Container(Container other) { // copy constructor
this();
for(int i=0;i<other.size();i++) this.add(other.at(i));
}
/** return true is this collection is empty, else return false. */
public synchronized boolean isEmpty() {return _sp==0;}
/** add an Object to this set */
public synchronized void add (Object p){
if (_sp==_data.length) rescale(RESCALE);
_data[_sp] = p; // shellow copy semantic.
_sp++;
}
/** returns the actual amount of Objects contained in this collection */
public synchronized int size() {return _sp;}
/** returns true if this container contains an element which is equals to ob */
public synchronized boolean isMember(Object ob) {
return get(ob)!=-1;
}
/** return the index of the first object which equals ob, if none returns -1 */
public synchronized int get(Object ob) {
int ans=-1;
for(int i=0;i<size();i=i+1)
if(at(i).equals(ob)) return i;
return ans;
}
/** returns the element located at the ind place in this container (null if out of range) */
public synchronized Object at(int p){
if (p>=0 && p<size()) return _data[p];
else return null;
}
Making a class safe for multi-threaded access is a complex subject. If you are not doing it in order to learn about threading, you should try to find a library that does it for you.
Having said that, a place to start is by imagining two separate threads executing a method line by line, in an alternating fashion, and see what would go wrong. For example, the add() method as written above is vulnerable to data destruction. Imagine thread1 and thread2 calling add() more or less at the same time. If thread1 runs line 2 and before it gets to line 3, thread2 runs line 2, then thread2 will overwrite thread1's value. Thus you need some way to prevent the threads from interleaving like that. On the other hand, the isEmpty() method does not need synchronization since there is just one instruction that compares a value to 0. Again, it is hard to get this stuff right.
You can check the following documentation about synchronized methods: http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
By adding the synchronized keyword two things are guaranteed to happen:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
So whenever you need to guarantee that only one thread accesses your variable at a time to read/write it to avoid consistency issues, one way is to make your method synchronized.
My advice to you is to first read Oracle's concurrency tutorial.
A few comments:
Having all your methods synchronized causes bottlenecks
Having _data variable public is a bad practice and will difficult concurrent programming.
It seems that you are reimplementing a collection, better use existing Java's concurrent collections.
Variable names would better not begin with _
Avoid adding comments to your code and try to have declarative method names.
+1 for everybody who said read a tutorial, but here's a summary anyway.
You need mutual exclusion (i.e., synchronized blocks) whenever it is possible for one thread to create a temporary situation that other threads must not be allowed to see. Suppose you have objects stored in a search tree. A method that adds a new object to the tree probably will have to reassign several object references, and until it finishes its work, the tree will be in an invalid state. If one thread is allowed to search the tree while another thread is in the add() method, then the search() function may return an incorrect result, or worse (maybe crash the program.)
One solution is to synchronize the add() method, and the search() method, and any other method that depends on the tree structure. All must be synchronized on the same object (the root node of the tree would be an obvious choice).
Java guarantees that no more than one thread can be synchronized on the same object at any given time. Therefore, no more than one thread will be able to see or change the internals of the tree at the same time, and the temporary invalid state created inside the add() method will be harmless.
My example above explains the principle of mutual exclusion, but it is a simplistic and inefficient solution to protecting a search tree. A more practical approach would use reader/writer locks, and synchronize only on interesting parts of the tree rather than on the whole thing. Practical synchronization of complex data structures is a hard problem, and whenever possible, you should let somebody else solve it for you. E.g., If you use the container classes in java.util.concurrent instead of creating your own data structures, you'll probably save yourself a lot of work (and maybe a whole lot of debugging).
You need to protect variables that form the object's state. If these variables are used in static method, you have to protect them as well. But, be careful, following example is wrong:
private static int stateVariable = 0;
//wrong!!!!
public static synchronized void increment() {
stateVariable++;
}
public synchronized int getValue() {
return stateVariable;
}
It seems that above is safe, but these methods operate on different locks. Above is more or less corresponds to following:
private static int stateVariable = 0;
//wrong!!!!
public static void increment() {
synchronized (YourClassName.class) {
stateVariable++;
}
}
public synchronized int getValue() {
synchronized (this) {
return stateVariable;
}
}
Notice that different locks are used when mixing static and object methods.
Related
Given:
public class NamedCounter{
private final String name;
private int count;
public NamedCounter(String name) { this.name = name; }
public String getName() { return name; }
public void increment() { count++; }
public int getCount() { return count; }
public void reset() { count = 0; }
}
Which three changes should be made to adapt this class to be used safely by multiple threads? (Choose three.)
A. declare reset() using the synchronized keyword
B. declare getName() using the synchronized keyword
C. declare getCount() using the synchronized keyword
D. declare the constructor using the synchronized keyword
E. declare increment() using the synchronized keyword
Answers are A, C, E. But I don't understand why. According to synchronized keyword only used for manipulation operations. So why answer C?
This question comes from SCJP dumps.
The JVM uses the synchronized keyword to tell it when a variable's contents need to be made visible across threads. In the posted example not only is the increment method unsafe (the postincrement operator takes multiple steps to act, so that another thread can interfere with it while the increment is in progress) but all the methods that touch the count variable -- increment, reset, and getCount -- need the synchronized keyword to indicate that the count variable could be changed in another thread. Otherwise the JVM could perform optimizations like caching the value or eliminating the bytecode altogether, because it is free to reason about the code without taking into account the possibility of multithreaded access.
There are alternatives to synchronized here; for instance an AtomicInteger would work too, using it for count would make sure the value would change atomically and would be accessed in a way that is visible to all threads. But as the question is worded answers A, C, and E are all necessary.
Answer D is wrong because declaring a constructor as synchronized isn't valid syntax, and if it was valid it wouldn't accomplish anything for you. Synchronization protects against sharing across threads, but the constructor call doesn't share anything so there's nothing to protect.
Answer B is wrong because the name is an immutable object passed in as a constructor argument and assigned to a final instance member; since it is published safely and cannot change, synchronization is unnecessary.
This may seem like pedantry but is really me questioning my fundamental assumptions.. :)
In the java documentation on synchronised methods, there is the following example:
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
Is the synchronized keyword really required on the value method? Surely this is atomic and whether the value is retrieved before or after any calls to related methods on other threads makes little difference? Would the following suffice:
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public int value() {
return c;
}
}
I understand that in a more complex case, where multiple private variables were being accessed then yes, it would be essential - but in this simple case, is it safe to assume that this can be simplified?
Also, I suppose that there is a risk that future modifications may require the value method to be synchronised and this could be forgotten, leading to bugs, etc, so perhaps this counts somewhat as defensive programming, but I am ignoring that aspect here.. :)
Yes, synchronized is really required on value(). Otherwise a thread can call value() and get a stale answer.
Surely this is atomic
For ints I believe so, but if value was a long or double, it's not. It is even possible to see only some of the bits in the field updated!
value is retrieved before or after any calls to related methods on other threads makes little difference?
Depends on your use case. Often it does matter.
Some static analysis software such as FindBugs will flag this code as not having correct synchronization if value() isn't also synchronized.
synchronized is required for both reading and writing a variable from another thread. This guarantees
that values will be copied from cache or registers to RAM (granted this is important for writing not reading)
it establishes that writes will happen before reads if they appear so in code. Otherwise the compiler is free to rearrange lines of bytecode for optimization
Check Effective Java Item 66 for a more detailed analysis
I have a counter and multiple threads access the getCount method. The code is like the following:
public class ThreadSafeMethod {
public static int counter = 0;
public static int getCount() {
return counter++;
}
}
Is the method thread safe? My understanding is that because counter++ is not atomatic, it is not safe. Then how to make it safe? If we add synchronized keyword, what object will be synchronized?
You are correct in your analysis when you say that it's not thread safe because the operation is not atomic. The retrieval of the value and the increment are not thread safe. Multiple calls to this method (whether it has parameters or not) access the same non-local variable.
Adding synchronized to this method makes it thread-safe. When adding to a static method, then the Class object is the object which is locked.
An alternative to making it thread-safe is to replace the int with an AtomicInteger, which has its own atomic getAndIncrement method.
No, a parameter-less method is not inherently thread-safe - the lack of parameters makes no difference in this example.
The read from (and write to) the counter variable is not guaranteed to be either atomic or consistent between threads.
The simplest change is to simply make the method synchronized:
public static synchronized int getCount() {
return counter++;
}
(The simplest is not always the "best" or "correct", but it will be sufficient here, assuming that no other code touches the public counter variable.)
See this answer for how a synchronization of a static method works - as can be imagined, it is the Class itself that is used as the monitor.
Using the synchronised keyword on the static function will 'lock' the function to one thread at a time to ensure that two threads can not mess with the same variable. With what you propose, I believe anything that gets accessed or modified in that function will be thread safe.
Just as you say the counter++ operation is non atomic so giving multiple threads access at once will result in undefined behaviour. In thread safety, the issue is almost always having synchronized access to shared resources such as static variables.
The lock which a thread acquires when declaring the method synchronized belongs to that class. Say we had two methods in a class
public synchronized void foo() {...}
public synchronized void bar() {...}
If one thread enters foo() it acquires the lock for the class, and any other thread trying to access foo() OR bar() will block until the first thread has finished. To overcome this, we can lock on seperate objects within the methods.
// Declare 2 objects to use as locks within the class
private Object fooLock = new Object();
private Objecy barLock = new Object();
// lock on these objects within the method bodies
public void foo {
synchronized(fooLock) { /* do foo stuff */ }
}
public void bar() {
synchronized(barLock) {/* do bar stuff */}
}
Now 2 threads can access the foo() and bar() simultaneously.
There's a lot of material on the web on Thread safety, I'd recommend this set of tutorials if yo want to know more about multithreading with locks / executor services and stuff.
I am confused about synchronizing an instance method and a static method.
I want to write a thread safe class as follow :
public class safe {
private final static ConcurrentLinkedQueue<Object> objectList=
new ConcurrentLinkedQueue<Object>();
/**
* retrieves the head of the object and prints it
*/
public synchronized static void getHeadObject() {
System.out.println(objectList.peek().toString());
}
/**
* creates a new object and stores in the list.
*/
public synchronized void addObject() {
Object obj=new Object();
objectList.add(obj);
}
}
Synchronizing on a static method will lock on safe.class lock and synchronizing on a instance method will lock on this .and hence an inconsistent state will be reached.
If I want to achieve a consistent state for a below code snippet how can that be achieved?
First, ConcurrentLinkedQueue does not require explicit synchronization. See this answer.
Second, you always can synchronize object you are accessing:
public class safe {
private final static ConcurrentLinkedQueue<Object> objectList=
new ConcurrentLinkedQueue<Object>();
/**
* retrieves the head of the object and prints it
*/
public static void getHeadObject() {
synchronized(objectList){
System.out.println(objectList.peek().toString());
}
}
/**
* creates a new object and stores in the list.
*/
public void addObject() {
Object obj=new Object();
synchronized(objectList){
objectList.add(obj);
}
}
}
EDIT: I'm assuming you meant Queue<Object> objectList instead of ConcurrentLinkedQueue<Object> objectList. ConcurrentLinkedQueue<Object> already does all of your thread safety for you, meaning you can call objectList.peek() all you want without worrying about race conditions. This is great if you're developing multi-threaded programs but not so great for learning about thread safety.
Your methods need not be synchronized, assuming you have one thread operating on one instance of the object at a time, but however if you need to have multiple instances of the class that all refer to the same static class variable, you need to synchronized over the class variable like so:
public static void getHeadObject() {
synchronized(safe.objectList) {
System.out.println(objectList.peek().toString());
}
}
This locks the objectList and does not allow it to be read or written to in any other thread as soon as the program is inside the synchronization block. Do the same for all other methods to be synchronized.
NOTE:
However, since you are doing only one simple get operation List.peek(), you really don't need to synchronize over the objectList since in a race condition, it'll get either one value of the List or another. The problem with race conditions is when multiple complex read/write operations are performed, with the value changing in between them.
For example, if you had a class PairInt with a PairInt.x and PairInt.y fields, with the constraint that x = 2y, and you wanted to do
System.out.println(myIntPair.x.toString() + ", " + myIntPair.y.toString());
and another thread was updating the value of x and y at the same time,
myIntPair.y = y + 3;
myIntPair.x = 2 * y;
And the write thread modified myIntPair in between your read thread's myIntPair.x.toString() and myIntPair.y.toString() you might get an output that looks like (10, 8), which means if you are operating on the assumption that x == 2 * y could crash your program.
In that case, your read needs to use a synchronized, but for more simpler things like peek() on a simple object that is being added or deleted, not modified while in the queue, the synchronized can, in most cases be dropped. In fact, for string, int, bool, and the like, the synchronized condition for a simple read should be dropped.
However, writes should always be synchronized on operations that are not explicitly thread safe, i.e. already handled by java. And as soon as you acquire more than one resource, or require that your resource stay the same throughout the operation as you do multiple lines of logic to it, then you MUST USE synchronized
A few comments:
Java conventions:
class names should be in CamelCase (i.e. call your class Safe, not safe)
static comes before synchronized in methods declaration
static comes before final in fields declaration
as others have already said, ConcurrentLinkedQueue is already thread safe, so there is no need for synchronization in the example you give.
mixing static and non static methods the way you do looks weird.
assuming that your actual use case is more complicated and you need a method to run atomic operations, then your code does not work, as you pointed out, because the 2 synchronized methods don't synchronize on the same monitor:
public static synchronized getHeadObject(){} //monitor = Safe.class
public static synchronized addObject(){} //monitor = this
So to answer your specific question, you could use a separate static object as a lock:
public class Safe {
private static final ConcurrentLinkedQueue<Object> objectList =
new ConcurrentLinkedQueue<Object>();
// lock must be used to synchronize all the operations on objectList
private static final Object lock = new Object();
/**
* retrieves the head of the object and prints it
*/
public static void getHeadObject() {
synchronized (lock) {
System.out.println(objectList.peek().toString());
}
}
/**
* creates a new object and stores in the list.
*/
public void addObject() {
synchronized (lock) {
Object obj = new Object();
objectList.add(obj);
}
}
}
When a class field is accessed via a getter method by multiple threads, how do you maintain thread safety? Is the synchronized keyword sufficient?
Is this safe:
public class SomeClass {
private int val;
public synchronized int getVal() {
return val;
}
private void setVal(int val) {
this.val = val;
}
}
or does the setter introduce further complications?
If you use 'synchronized' on the setter here too, this code is threadsafe. However it may not be sufficiently granular; if you have 20 getters and setters and they're all synchronized, you may be creating a synchronization bottleneck.
In this specific instance, with a single int variable, then eliminating the 'synchronized' and marking the int field 'volatile' will also ensure visibility (each thread will see the latest value of 'val' when calling the getter) but it may not be synchronized enough for your needs. For example, expecting
int old = someThing.getVal();
if (old == 1) {
someThing.setVal(2);
}
to set val to 2 if and only if it's already 1 is incorrect. For this you need an external lock, or some atomic compare-and-set method.
I strongly suggest you read Java Concurrency In Practice by Brian Goetz et al, it has the best coverage of Java's concurrency constructs.
In addition to Cowan's comment, you could do the following for a compare and store:
synchronized(someThing) {
int old = someThing.getVal();
if (old == 1) {
someThing.setVal(2);
}
}
This works because the lock defined via a synchronized method is implicitly the same as the object's lock (see java language spec).
From my understanding you should use synchronized on both the getter and the setter methods, and that is sufficient.
Edit: Here is a link to some more information on synchronization and what not.
If your class contains just one variable, then another way of achieving thread-safety is to use the existing AtomicInteger object.
public class ThreadSafeSomeClass {
private final AtomicInteger value = new AtomicInteger(0);
public void setValue(int x){
value.set(x);
}
public int getValue(){
return value.get();
}
}
However, if you add additional variables such that they are dependent (state of one variable depends upon the state of another), then AtomicInteger won't work.
Echoing the suggestion to read "Java Concurrency in Practice".
For simple objects this may suffice. In most cases you should avoid the synchronized keyword because you may run into a synchronization deadlock.
Example:
public class SomeClass {
private Object mutex = new Object();
private int val = -1; // TODO: Adjust initialization to a reasonable start
// value
public int getVal() {
synchronized ( mutex ) {
return val;
}
}
private void setVal( int val ) {
synchronized ( mutex ) {
this.val = val;
}
}
}
Assures that only one thread reads or writes to the local instance member.
Read the book "Concurrent Programming in Java(tm): Design Principles and Patterns (Java (Addison-Wesley))", maybe http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html is also helpful...
Synchronization exists to protect against thread interference and memory consistency errors. By synchronizing on the getVal(), the code is guaranteeing that other synchronized methods on SomeClass do not also execute at the same time. Since there are no other synchronized methods, it isn't providing much value. Also note that reads and writes on primitives have atomic access. That means with careful programming, one doesn't need to synchronize the access to the field.
Read Sychronization.
Not really sure why this was dropped to -3. I'm simply summarizing what the Synchronization tutorial from Sun says (as well as my own experience).
Using simple atomic variable access is
more efficient than accessing these
variables through synchronized code,
but requires more care by the
programmer to avoid memory consistency
errors. Whether the extra effort is
worthwhile depends on the size and
complexity of the application.