What is the difference between a synchronized function and synchronized block? [duplicate] - java

This question already has answers here:
What is the difference between a synchronized method and synchronized block in Java? [duplicate]
(6 answers)
Closed 5 years ago.
what is the difference between
public synchronized void addition()
{
//something;
}
and
public void addtion()
{
synchronized (//something)
{
//something;
}
}
If I am wrong Ignore this question.

public synchronized void addition() {...}
is equivalent to
public void addition() {
synchronized(this) { ... }
}
Now, if you replace the this with a different object reference, the locking will be done using that other object's monitor.

The second one doesn't compile. If you meant
public void addition()
{
synchronized (this)
{
//something;
}
}
Then they're equivalent.

If the second example is synchronized (this), then there's no difference. If it's something else, then the lock object is different.

public synchronized void addition()
{
//something;
}
is the same as:
public void addtion()
{
synchronized (this)
{
//something;
}
}
Whereas, in your second example, you may want to synchronize using something different from this.

it the first one only one thread can execute whole method at a time whereas in second one only one thread can execute that synchronized block if not used this as parameter.
here is a duplicate of it Is there an advantage to use a Synchronized Method instead of a Synchronized Block?

Synchronized method synchronizes on "this" object. And if it is a block you can choose any object as a lock.

I)
public synchronized void addition()
{
//something;
}
II)
public void addtion()
{
synchronized (//something)
{
//something;
}
}
In version I (method level synchronization), at a time, complete body of method can only be executed by one thread only.
however, version II is more flexible cause it's called block level synchronization and you can add some lines above synchronized (//something) to execute them parallely. it should be synchronized (this)
version II should be preferred as only that code needs to be multithreaded (within synchronized) which are critical.

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.

synchronization in java (object and static methods)

I have few queries regarding Synchronization in Java. I have read a lot of content online and have feeded myself with lot of information and so with multiple doubts.
I will list down my queries, so please anyone help me out with my doubts.
Object level synchronization :
1) For following code sample.
public synchronized void a(){
//todo
}
}
What will be the LOCK used. Will it automatically be lock on "this" as we have it in case below sample code ?
public void a(){
synchronized (this) {
//TODO
}
}
2) We have multiple methods code blocks locking on "this".
public void a(){
synchronized (this) {
//TODO
}
}
public synchronized void b(){
synchronized (this) {
//TODO
}
}
So does this means that if code block of b() is locked, then any other thread wont be able to access a() as well at the same time as they have a lock on the object(this)?
Class level synchronization :
3) For the following code
public static void c(){
synchronized (Main.class) {
//todo
}
}public static void d(){
synchronized (Main.class) {
//todo
}
}public static void e(){
//no syncronization here
}
Question 1 : IF c() is locked will any other thread be able to access d() which has synchronized block as well ?
Question 2: If c() is under lock, will any other thread will be able to access e() which is a non synchronized method ?
Yes "this" is the lock
Yes
The lock is on Main.class so if the lock in c is already acquired d can't be accessed by another thread.
in point 3. e() can always be accessed by multiple threads no matter what since its not synchronized.
Hope that helps :)

How class level lock is acquired

public synchronized int getCountOne() {
return count++;
}
Like in above code synchronizing on the method is functionally equivalent to having a synchronized (this) block around the body of the method. The object "this" doesn't become locked, rather the object "this" is used as the mutex and the body is prevented from executing concurrently with other code sections also synchronized on "this."
On similar grounds what is used as a mutex when we acquire a class level lock.As in if we have a function
public static synchronized int getCountTwo() {
return count++;
}
obviously two threads can simultaneously obtain locks on getCountOne(object level lock) and getCountTwo(class level lock). So as getCountOne is analogous to
public int getCountOne() {
synchronized(this) {
return count++;
}
}
is there an equivalent of getCountTwo? If no what criteria is used to obtain a Class level lock?
On similar grounds what is used as a mutex when we acquire a class level lock
The class object itself will be used as mutex. The equivalent synchronized block for your static synchronized method will look like:
public static int getCountTwo() {
synchronized(ClassName.class) {
return count++;
}
}
ClassName is the name of the class containing that method.
See JLS Section §8.4.3.6:
A synchronized method acquires a monitor (§17.1) before it executes.
For a class (static) method, the monitor associated with the Class
object for the method's class is used.
For an instance method, the monitor associated with this (the object
for which the method was invoked) is used.
Emphasis mine.
Object level locking:
Object level locking is mechanism when you want to synchronize a non-static method or non-static code block such that only one thread will be able to execute the code block on given instance of the class. This should always be done to make instance level data thread safe. This can be done as below :
public class DemoClass
{
public synchronized void demoMethod(){}
}
or
public class DemoClass
{
public void demoMethod(){
synchronized (this)
{
//other thread safe code
}
}
}
or
public class DemoClass
{
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
Class level locking:
Class level locking prevents multiple threads to enter in synchronized block in any of all available instances on runtime. This means if in runtime there are 100 instances of DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads. This should always be done to make static data thread safe.
public class DemoClass
{
public synchronized static void demoMethod(){}
}
or
public class DemoClass
{
public void demoMethod(){
synchronized (DemoClass.class)
{
//other thread safe code
}
}
}
or
public class DemoClass
{
private final static Object lock = new Object();
public void demoMethod(){
synchronized (lock)
{
//other thread safe code
}
}
}

Java Synchronization inside Another Thread

I have a quick question about Java synchronization.
Please assume the following code:
public class Test {
private String address;
private int age;
public synchronized setAddress(String a) {
address = a;
}
public synchronized setAge(int a) {
age = a;
}
public synchronized void start() {
...
listener = new Thread(new Runnable(){
public void run() {
...
setAge(10);
...
synchronized(Test.this) {
address = null;
}
}
}
}
}
I am a little bit unsure about Java synchronization when synchronized method or synchronized block is called inside another thread.
Assume the thread running class Test as A, and
the listener thread B.
Then if I execute the code above, does it guarantee that synchronized method calls and synchronized block are synchronized with the A (the thread running Test class) ?
Thank you for reading.
No,
The synchronized methods are locking the Test instance, while the synchronized block is locking the Test class object.
See Java synchronized static methods: lock on object or class and Java Synchronized Block for .class

Categories