1

The question may seem pretty obvious, but it's not clear to me anyway.

I have the following class:

public class MyClass{

    private Object lock = new Object();
    private boolean flag;


    public void method(){
        //Start synchronization block
        if(!flag){
            flag = true;
        //end synchronization block
            //do some bulk operation, should be synchronized
        }
        //some other staff
    }
}

The thing is I cannot put the piece of code I need to be synchronized, because it will not be correct. How to do such synchronization? Maybe there's something from java.util.concurrent that I could make use of.

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • 2
    you can `synchronization block`.. – SatyaTNV Sep 29 '15 at 11:27
  • possible duplicate of [Is there an advantage to use a Synchronized Method instead of a Synchronized Block?](http://stackoverflow.com/questions/574240/is-there-an-advantage-to-use-a-synchronized-method-instead-of-a-synchronized-blo) – Thomas Weller Sep 29 '15 at 11:29
  • @St.Antario why do you want to synchronize half? I don't think it is possible – DDphp Sep 29 '15 at 11:36

5 Answers5

6

You can also do it without explicit synchronization, using an AtomicBoolean:

public class MyClass{

    private AtomicBoolean flag = new AtomicBoolean(false);

    public void method(){
        if(flag.compareAndSet(false, true)) {
            //do some bulk operation, should be synchronized
        }
        //some other staff
    }
}

This will only enter the block if nothing has entered it before, and is thread safe.

Of course, there may be other things in the block which also require synchronization. However, this works for the stated problem.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
2

Your code looks like a perfect use case for AtomicBoolean, which has a method compareAndSet which atomically checks the value of the boolean and sets it if the check returns the expected value:

private AtomicBoolean flag = new AtomicBoolean();

public void method() {
    if (flag.compareAndSet(false, true)) {
        // ...
    }

    // other stuff
}
Jesper
  • 202,709
  • 46
  • 318
  • 350
1

You can grab the object's monitor using synchronized(this){/*ToDo - synchronised code here*/}

Alternatively, you can synchronise on one of the object's fields if acquiring the object's monitor will cause concurrency issues.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

This way you can use synchronized block:

synchronized(this)
{
    // synchronized block
}
DDphp
  • 479
  • 2
  • 5
  • 17
0

Don't forget about java.util.concurrent.locks.Lock, which is more powerful (and therefore, more dangerous) than Java's built-in locking. It lets you do things like this:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

final Lock myLock = new ReentrantLock();

myLock.lock();
if (...) {
    ...
    myLock.unlock();
    ...
} else {
    myLock.unlock();
    ...
}
Solomon Slow
  • 25,130
  • 5
  • 37
  • 57