Synchronization on "this" or private Object in Java? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Avoid synchronized(this) in Java?
What is the difference between the two pieces of code ? What are advantages and disadvantages of each?
1)
public class Example {
private int value = 0;
public int getNextValue() {
synchronized (this) {
return value++;
}
}
}
2)
public class Example {
private final Object lock = new Object();
private int value = 0;
public int getNextValue() {
synchronized (lock) {
return value++;
}
}
}

The main reason why I would choose the 2nd approach is that I do not control what the clients do with the instances of my class.
If, for some reason, somebody decides to use an instance of my class as a lock, they will interfere with the synchronization logic within my class:
class ClientCode {
Example exampleInstance;
void someMethod() {
synchronized (exampleInstance) {
//...
}
}
}
If, within my Example class, I'm using a lock that no one else can see, they cannot interfere with my logic and introduce an arbitrary mutex like in the above scenario.
To sum up, this is just an application of the information hiding principle.

I would prefer the second option if I need to execute two different tasks simultaneously which are independent of each other.
e.g.:
public class Example {
private int value = 0;
private int new_value = 0;
private final Object lock1 = new Object();
private final Object lock2 = new Object();
public int getNextValue() {
synchronized (lock1) {
return value++;
}
}
public int getNextNewValue() {
synchronized (lock2) {
return new_value++;
}
}
}

I would say the second method is better. Consider the following situation:
public class Abc{
private int someVariable;
public class Xyz {
//some method,synchronize on this
}
//some method, and again synchronize on this
}
In this situation this is not the same in the two methods. One is a method of the inner class. Hence, it is better to use a common object for synchronization. E.g., synchronized (someVariable).

I think it really depends on the situation. Lets say your class is a subclass and the super class has a method that has synchronization. And lets say you are working with the same data set and want to maintain integrity within your method as well. Then definitely approach 1 is what you should be using.
Otherwise second approach would work better based on what Costi mentioned

Related

How to avoid accessing the same static counter while multithreading [duplicate]

This question already has answers here:
How to synchronize a static variable among threads running different instances of a class in Java?
(5 answers)
Closed 3 years ago.
Im new to multithreading and it's a bit confusing. How could I use the synchronize key to give an output of : 1 a then 2 b ? In other words, I want the first thread to access the static variable x, increment it and then the second thread to start.
public class Test1 extends Thread{
static int x=0;
String name;
Test1(String n){ name=n;}
public void increment() {
x=x+1;
System.out.println(x+" "+ name);
}
public void run() {
this.increment();
}
}
public class Main {
public static void main(String args[]) {
Test1 a= new Test1("a");
Test1 b= new Test1("b");
a.start();
b.start();
}
}
You can use synchronized static method (in the increment anyway you are just operating on the static field so why not to make it static?).
public static synchronized void increment() {
x=x+1;
System.out.println(x+" "+ name);
}
Such method is synchronizing on the whole class object.
If you really don't want for some reason to make this method static you can explicitely synchronize the critical section on the class object
public void increment() {
synchronized(Test1.class) {
x=x+1;
System.out.println(x+" "+ name);
}
}
I'd suggest using an AtomicInteger with a call to incrementAndGet(). This will atomically increment the variable as well as prevent other threads from returning calls to the variable until preceding locks are removed, so your increment method would be:
System.out.println(x.incrementAndGet()+" "+ name);
You can also use a synchronised block as other users have posted, but the drawback of both of the suggestions is that you are sacrificing control of a lock object, since the synchronised keyword on a method is equivalent to:
synchronized (this) { }
And referring to a class object does not keep the object internal to the class.

2 ways for synchronize, what is the difference [duplicate]

This question already has answers here:
Synchronization on "this" or private Object in Java? [duplicate]
(4 answers)
Closed 4 years ago.
I found 2 ways for synchronize method:
First:
public static Integer number = 0;
public synchronized static void myMethod(){
number++;
number--;
}
Second:
public static Integer number = 0;
private static final Object mySemaphoreLock = new Object();
public static void myMethod(){
synchronized (mySemaphoreLock){
number++;
number--;
}
}
Are these two methods the same? What is the difference between them?
In the second case lock object s available only for your class.
In the first method some other code can acquire lock accidentally or on purpose and make your code not working as expected.
For example if first case it is possible to do the following
public class MyBadClass {
public static void badStuff() { //Acquire lock on class object and do forever loop. Because of that you will not be able to call YourClass.myMethod() in your first option
synchronized (YourClass.class) {
while(true);
}
}
}
These two methods are using different objects to synchronize on (class instance vs class field).
Your first method:
public synchronized static void myMethod(){
number++;
number--;
}
can be expressed as
public static void myMethod(){
synchronized (YourClass.class) {
number++;
number--;
}
}
so you are using a different object to synchronize on (YourClass's class object vs class's static field (mySemaphoreLock)) than
public static void myMethod() {
synchronized (mySemaphoreLock) {
number++;
number--;
}
}
In your example there's no difference, but you cannot rule out someone else (think 3rd-party code) that would also want to synchronize on your class's object (for reasons unknown) - that would impact the behaviour of your code.
In general it would be some other code doing something like:
class SomeOtherClass {
public void someOtherMethod() {
// for some reason SomeOtherClass synchronizes on YourClass.class
synchronized (YourClass.class) {
/* long running operation */
}
}
}
so even if you invoke YourClass.myMethod() in parallel, one would need for to wait for the other to finish.
If you choose the implemenation with mySemaphoreLock, that wouldn't happen - this piece of code would execute concurrently (as they use different objects to synchronize on) - so no competition.

Class which can allow to create Only 'n' number of Objects

This question is similar to singleton, but i need to create a class that can allow 'n' number of objects only, Below is my code
public class MSInt {
private static MSInt instance = null;
private static int count = 0;
private MSInt()
{
}
public static MSInt getInstance()
{
if(count < 5){
instance = new MSInt();
count++;
return instance;
}
else
{
return null;
}
}
}
This is working but i am thinking a better solution than this if any.
I think this would be a much cleaner way of doing it. You wouldn't need any counters.
Also it looks nice.
import java.util.ArrayList;
public class MSInt {
private static int MAX_OBJS = 10;
private static ArrayList<MSInt> instances = new ArrayList<MSInt>(MAX_OBJS);
private MSInt() {}
public static MSInt mkInstance() {
if(instances.size() < MAX_OBJS){
MSInt obj = new MSInt();
instances.add(obj);
return obj;
} else {
return null;
}
}
public static ArrayList<MSInt> getInstances() {
return instances;
}
}
Your Code is :
private static MSInt instance = null;
this is overwrite methods;
use like this Array :
private static MSInt[] instance = null;
and use a for loop:
for(int i=0;i<5;i++)
{
instance[i] = new MSInt();
return instance[i];
}
I suggest you to use a decorator pattern
so create a class LimitedList<T> extends AbstractList<T> and override add methods in order to check if size is exceeded
I've put code here (gist)
Few suggestions:
replace public static MSInt getInstance() to public static MSInt getInstance(int number). That way you will be able to specify every time what object you are going to get.
Define difference between instances. What attributes does your instances possess? In your example all objects looks the same - it becomes unclear why do you need more than one of them.
Think about initialization. Do you need lazy initialization, or can you initialize all the instances in class initialization. Then you can declare them public static final and deny defining getInstance()
BTW, enum is class that has exactly n instances (by design). It's very likely that defining MSInt as enum will be the most convenient for you.
Using an array or collection means that garbage collection won't remove any of your instances without your knowledge, and it means you can retrieve instances later if required. Using an an MSInt[] might be most practical because it is already capable of making sure only a certain number of objects exist in it. The getInstance() method then loops through the array and if it finds an empty slot, creates a new instances, puts it in the empty spot and returns the result.
public class MSInt {
private static MSInt[] instances = new MSInt[10];
private MSInt(){ }
public synchronized static MSInt getInstance() /*throws TooManyException*/{
for(int i = 0 ; i<instances.length() ; i++){
if(instances[i]==null){
MSInt ms = new MSInt();
instances[i] = ms;
return ms;
}
}
// throw new TooManyException("There are already 10 instances of MSInt");
return null;
}
}
Some exception handling might also be useful. You could throw a custom exception to show that too many instances already exist. Which would make it much more manageable later because you can then define more robust custom behavior for if the array is already full. By removing the comments in the class above and creating the below class, that should work nicely.
public class TooManyException extends Exception {
public TooManyException(String message){
super(message);
}
}
Hope this helps.

Acquiring inner-class lock using outer-class locks?

I have an outer class A and that has a public inner class, the structure is as follows -:
public class A{
public int x;
public class B{
private static final int y;
}
public synchronized int method1(){
return x+ B.y;
}
}
the question is if I used synchronized keyword on every method of the class A will it also lock the members of the inner class as well?
if I used synchronized keyword on every method of the class A will it also lock the members of the inner class as well?
No it won't.
You seem to be confused in a number of respects here.
Using a primitive mutex (e.g. via a synchronized method) only locks against other threads that are synchronizing on the same mutex.
When you call a synchronized instance method, the mutex you are acquiring is the mutex for this ... the target object.
In your example, it seems that you want to lock a static field, not an instance field.
If I understand correctly what you are trying to do, the correct way to do it is something like this:
public synchronized int method1(){
synchronized (B.class) {
return x + B.y;
}
}
Note that this involves acquiring two mutexes, so you need to make sure that your code always acquires them in the same order. (If you don't, then there is a risk of deadlocks.)
You would get the same effect if you created and called a synchronized static method on B for getting the value of the y field.
No, the inner class and outer class are two different class objects, they will not be the same. I suggest creating a field in the outer class to manually synchronize on.
An example with a single mutex on 2 objects. Both Objects can change a variable x.
public class A {
private Object mutex = new Object();
private int x;
private B b = new B();
public class B {
private int y;
public int method() {
synchronized(mutex) {
return x++;
}
}
}
public int method() {
synchronized(mutex) {
return x += b.y;
}
}
}

Thread-safety idiom for getters in a Java class other than "synchronized"

public class ThreadSafe {
private int aField;
public synchronized void setAField(int value) {
aField = value;
}
public synchronized int getAField() {
return aField;
}
}
public class ThreadSafeToo {
private volatile int aField;
public synchronized void setAField(int value) {
aField = value;
}
public int getAField() {
return aField;
}
}
public class DontKnowIfThreadSafeButMostLikelyYes {
private static int aField;
public synchronized void setAField(int value) {
aField = value;
}
public int getAField() {
return aField;
}
}
Questions:
Is DontKnowIfThreadSafeButMostLikelyYes thread-safe?
What would be the preferred idiom and why?
ThreadSafeToo does not need a synchronized method: volatile assignment is atomic and provides visibility guarantees.
DontKnowIfThreadSafeButMostLikelyYes is not thread safe: you need to synchronize reads AND writes to shared variables.
Preferred idiom is subjective, but in your case, the efficient approach is:
public class ThreadSafeToo {
private volatile int aField;
public void setAField(int value) { aField = value; }
public int getAField() { return aField; }
}
Your class DontKnowIfThreadSafeButMostLikelyYes is not thread safe because a static variable is not different from an instance variable from point of synchronization. Besides this the result will not be the same as in the other cases.
Also the second question is opinion based.
As far as I know DontKnowIfThreadSafeButMostLikelyYes is not thread-safe, because 2 threads could set and get aField at the same moment -> problem
There is no difference if you put the static or not. Both would be not thread-safe.
I think there is no real preferred idom. In this case I would choose the first way. But you can also use the second one or you could use locks.
Is DontKnowIfThreadSafeButMostLikelyYes thread-safe?
No, because when getter & setter are being called the same moment getter might return old value.
What would be the preferred idiom and why?
In this case the 2nd class is correctly synchronized & is thread safe

Categories