Do I need synchronise on objects which guarantee happen-before? - java

I have a collection which guaranteed to be visible across threads. However that doesn't guarantee visibility of states of items which are stored in this collection(eg. if I have collection of StringBuilder(mutable, not thread safe) then I have to synchronize on each item in collection during write/read, right?). So, what happens when I have collection of objects which are used for guaranteeing happen-before by themselves(eg. countdownlatch). Do I need to synchronize on each item somehow when calling await/countDown? Code below roughly illustrate this dilemma:
public class SyncQuestion {
final List<CountDownLatch> lathces = new ArrayList<CountDownLatch>();
SyncQuestion() {
lathces.add(new CountDownLatch(1));
}
public static void main(String[] args) throws InterruptedException {
final SyncQuestion sync = new SyncQuestion();
final Thread sleepingThread = new Thread() {
public void run() {
for (CountDownLatch latch : sync.lathces) {
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
};
final Thread wakingThread = new Thread() {
public void run() {
for (CountDownLatch latch : sync.lathces) {
latch.countDown();
}
};
};
sleepingThread.start();
wakingThread.start();
sleepingThread.join();
wakingThread.join();
}
}
Please correct me in my assumptions, if they are wrong.

A CountDownLatch is basically a wrapper on AbstractQueuedSynchronizer whose state is a volatile int that is mutated via Unsafe.compareAndSwapInt (which is an atomic operation).
Therefore in this specific case, as Cameron Skinner said, there is no need to synchronize because it enforces that happens-before for you.

I don't believe you need to manually synchronize in this case because the latches are internally thread-safe.

Related

Lock objects for all threads?

I have this small sample of code, while modifying the list, i lock it with synchronized, but while reading the list it comes to ConcurrentModificationException, because without "synchronized" the lock has no effect. Is it possible to lock an object for all threads which use the object, even the un-synchronized, too?
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Test {
public static void main(String[] args) {
final Random r = new Random(System.currentTimeMillis());
List<Integer> list = new ArrayList<>();
new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (list) {
list.add(r.nextInt());
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while (true) {
for (Integer i : list) {
System.out.println(i);
}
}
}
}).start();
}
}
the backgorund is that i dont want to change all pieces in my code which read the object
You might consider using a concurrent implementation of List, instead of ArrayList. Perhaps a CopyOnWriteArrayList.
final List<Integer> list = new CopyOnWriteArrayList<Integer>();
Is it possible to lock an object for all threads which use the object.
In a word, No. When one thread enters a synchronized(foo) {...} block, that does not prevent other threads from accessing or modifying foo. The only thing it prevents is, it prevents other threads from synchronizing on the same object at the same time.
What you can do, is you can create your own class that encapsulates both the lock and the data that the lock protects.
class MyLockedList {
private final Object lock = new Object();
private final List<Integer> theList = new ArrayList<>();
void add(int i) {
synchronized(lock) {
theList.add(i);
}
}
void printAll() {
synchronized(lock) {
for (Integer i : theList) {
System.out.println(... i ...);
}
}
}
...
}
If you can modify the function which concurrently uses the object, just add synchronized in every critical section:
while (true) {
synchronized(list){
for (Integer i : list) {
System.out.println(i);
}
}
}
if you can't , create a specified lock that is responsible for locking the threads:
Lock lock = new Lock();
new Thread(new Runnable(){
//...
synchronized(lock){
do unsynchonized function on list
}
//...
}).start();
new Thread(new Runnable(){
//...
synchronized(lock){
do unsynchonized function on list
}
//...
}).start();
the latter may slow down the process if one of the functions already doing some locking, but in this way you can ensure you always synchronize the access to concurrent objects.

How to restrict specific number of threads to synchronized block in java

I am not able to figure out this question. In a multi threaded environment - exactly 3 threads should be able to execute the synchronized block and rest should wait ?
What I understand is when we use synchronization or monitor one thread will wait until the other thread finishes its execution in side synchronized block or method. To achieve multiple thread to enter inside synchronized block or method we need to use wait(), notify(), notifyAll() i.e. inter thread communication, where wait() method when called on certain object it will takes its lock and give chances to other waiting threads.
So, I am wondering how to do the above question. I am not sure if I have put my question in right way. If its possible do we need to use java concurrent util package or can it be done in basic(core) thread functionality.
Use a semaphore with three permits:
Semaphores are often used to restrict the number of threads that can
access some (physical or logical) resource.
Using a semaphore would probably be the best solution to your problem, but it doesn't hurt to try your own solution, even though it's just for the sake of experimenting and maybe learning something new.
Here is a quick example of a lock implementation using LinkedBlockingQueue. This lock will only allow a certain number of threads to access the block of code between getKey() and returnKey():
public class Lock {
private int keys;
private LinkedBlockingQueue<Integer> q;
public Lock(int keys) throws InterruptedException {
q = new LinkedBlockingQueue<>();
while (q.size() != keys)
q.put(0);
}
public void getKey() throws InterruptedException {
q.take();
}
public void returnKey() throws InterruptedException {
q.put(0);
}
static Lock lck;
public static void main (String [] args) throws InterruptedException {
lck = new Lock(3);
Runnable r = new Runnable() {
#Override
public void run() {
try {
lck.getKey();
Lock.test();
lck.returnKey();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
for (int t = 0; t < 10; t ++)
new Thread(r).start();
}
public static void test() throws InterruptedException {
System.out.println("I am " + Thread.currentThread().getName());
Thread.sleep(1000);
}
}

Locking all the strings in a collection

I have a collection of strings which must be locked upon by a thread for computing some information. These strings are nothing but unique entities which must be handled by only one thread at a time. Any thread other than the current thread trying to acquire lock on any of these entities in the collection must wait for the current thread to complete its execution and release the lock on the collection. Two entirely different collection containing different strings can be worked upon by two different threads concurrently. I am stuck how to implement this. I tried googling. But all I found was how to lock a single string not many strings. Any idea would be helpful.
For example,
Thread one is working on apple, oranges and bananas.
Thread two wants to works on apple and peaches.
Thread two must wait until Thread one releases the lock.
Update:
Instead of looking upon the lock literally think of it as a permit to use the entity. For example, if you need to use apple, you must acquire permission. The thread must block until it gets permission for all the entities in its collection.
Let met put it in this way. Thread1 [apples, oranges, bananas] seeks permission to use the entities in the collection to a Manager. Lets assume the manager gave permission to Thread1. If another thread Thread2 [apples, peaches] seeks permission, the Manager should not give permission since permission for apples is already owned by Thread1 and Thread2 must be blocked. Once Thread1 tells the manager that it has completed its work, the Manager can give permission to Thread2. Meanwhile, if another thread Thread3 [guava, pineapple] seeks permission, the Manager should not block it and grant permission readily.
Instead of operating on many lock I would choose one synchronized storage of "locked" Strings.
That would hugely simplify synchronization.
Something like that:
private final Set<String> elementsInProgress = new HashSet<String>(); // not thread-safe, accessed only from blocks synchronized on it
public void process(Collection<String> input) throws InterruptedException {
for (String stringToProcess : input) {
synchronized (elementsInProgress) {
while (elementsInProgress.contains(stringToProcess)) {
elementsInProgress.wait();
}
elementsInProgress.add(stringToProcess);
}
doProcess(stringToProcess);
synchronized (elementsInProgress) {
elementsInProgress.remove(stringToProcess);
elementsInProgress.notifyAll();
}
}
}
private void doProcess(String s){/* ... */}
The code snippet is untested, btw )
How about starting with guava-libraries
import com.google.common.collect.Interners;
import com.google.common.collect.Interner;
Then create an an interner. Weak references are OK b/c it's the particular instance that holds the lock. You could use a ConcurrentMap (careful to use putIfAbsent) to do your interning, but...
Interner<String> namedLocks = Interners.newWeakInterner();
Then the client threads can simply use synchronized. I'm using Callable to represent the work.
public <T> void doWork(String name, Callable<T> work) {
synchronized(namedLocks.intern("name")) {
return work.call();
}
}
This will work if Thread 1 (apple, oranges, bananas) and Thread 2 (apple, peaches) can work on (for example) "oranges" and "peaches" concurrently. The 'work' variable in this case represents the work of 'oranges' independently.
If Thread 2 must wait until Thread 1 is done with all three items before starting any of its own, then it's a bit more complex but still manageable. The 'work' in this case represents 'apple+oranges+bananas'.
public <T> T doWork(List<String> names, Callable<T> work) {
// important to avoid deadlocks
names = new ArrayList<>(names);
Collections.sort(names);
return doWorkInternal(names.iterator());
}
private <T> T doWorkInternal(Iterator<String> names, Callable<T> work) {
if(names.hasNext()) {
synchronized(namedLocks.intern(names.next())) {
return doWorkInternal(names, work);
}
} else { // no more locks to acquire
return work.call();
}
}
In the above, you're acquiring each lock in sorted order (important for deadlock) as you recurse down the stack.
public class FruitRunnable implements Runnable {
// this is the actual lock
private static final Object lock = new Object();
// here we store which objects are currently used
private static final Set<String> usedObjects = new HashSet<String>();
// these are the objects a thread will need
private final String[] neededObjects;
public FruitRunnable(String... neededObjects) {
this.neededObjects = neededObjects;
}
#Override
public void run() {
acquireLock(neededObjects);
// between these two methods we can assure that there is
// no other thread working on our resources
work();
// important! release the resources afterwards!
releaseLock(neededObjects);
}
private void work() {
System.out.println("working: " + Arrays.toString(neededObjects));
try {
// work of 10 seconds
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void acquireLock(String[] fruits) {
// go into lock
synchronized (lock) {
// loop until we can acquire our resources
boolean success = false;
while (!success) {
success = true;
for (String s : fruits) {
if (usedObjects.contains(s)) {
// too bad this fruit is already in use
success = false;
}
}
// on success add all used fruits to the usedObjects Set and return
if (success) {
for (String s : fruits) {
usedObjects.add(s);
}
return;
}
// if we had no success we will wait until some other thread
// releases fruits
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void releaseLock(String[] fruits) {
synchronized (lock) {
// release the fruits and notify the other threads to re-check
for (String s : fruits) {
usedObjects.remove(s);
}
lock.notifyAll();
}
}
public static void main(String[] args) throws InterruptedException {
// starting the threads from your example
new Thread(new FruitRunnable("apple", "oranges", "bananas")).start();
new Thread(new FruitRunnable("apple", "peaches")).start();
Thread.sleep(2000);
new Thread(new FruitRunnable("guava", "pineapple")).start();
}
}
Find some comments on how it works in code.

Java Executors and per-thread (not per-work unit) objects?

I have a task that would benefit from the Thread Pool design pattern (many small tasks to be performed in parallel). I initially implemented a naive thread pool from scratch, with n Runnables all pulling work units from the same ConcurrentLinkedQueue until the queue is empty, then terminating. I then decided "hey, let's try the Executor in Java, because that is probably better-tested and more reliable than my naively designed system." Problem: in my implementation, each thread persisted until the queue was empty, using a while (!queue.isEmpty()), and got its own instance of a non-threadsafe object, let's call it SlowObject foo, that is time-consuming to construct. Trying to pass all Runnables that go into the Executor's pool an instance of the time-inefficient object fails because it is not thread-safe. Creating a new instance of SlowObject for each Runnable is undesirable because they are costly to construct.
Is there a way to say "how many threads are we using? Let's create one SlowObject for each thread, and then let the Runnables detect what thread we're on and look up the correct object to use?" This sounds brittle and failure-prone -- not sure what design pattern I should be looking at instead, though.
You're better off using a resource pool. Use something like this:
public class SlowObjectPool {
private static final int POOL_SIZE = 10;
private BlockingQueue<SlowObject> slowObjectQueue = new ArrayBlockingQueue(POOL_SIZE);
public SlowObjectPool() {
for (int i = 0; i < POOL_SIZE; i++) {
slowObjectQueue.put(new SlowObject());
}
}
public SlowObject take() throws InterruptedException {
return slowObjectQueue.take();
}
public void release(SlowObject slowObject) {
// TODO You may want to log a warning if this is false
slowObjectQueue.offer(slowObject);
}
}
You may want to make this a singleton as well. Then in your runnables:
public class MyRunnable implements Runnable {
private SlowObjectPool pool;
public MyRunnable(SlowObjectPool pool) {
this.pool = pool;
}
#Override
public void run() {
// The next line blocks until a SlowObject is available
SomeObject someObject = null;
try {
someObject = pool.take()
// Do something with someObject
} catch (InterruptedException ex) {
// Thread is being ended, allow to end
} finally {
if (someObject != null)
pool.release(someObject);
}
}
}
This will create the objects all at once when the pool is first created instead of creating them dynamically, that way none of your runnables have to wait for SomeObject instances to be created.
Java provides the concept of a ThreadLocal variable.
You can use it within your Runnable like this.
public class MyJob implements Runnable {
private static final ThreadLocal < SlowObject > threadLocal =
new ThreadLocal < SlowObject > () {
#Override protected SlowObject initialValue() {
// construct and return your SlowObject
}
};
public void run() {
// work with threadLocal.get()
}
}
Thereby for each thread running your Runnable only a single instance of your class SlowObject is created.

Controlling race condition at startup

I have some code that I want to have some one time initialisation performed. But this code doesn't have a definite lifecycle, so my logic can be potentially invoked by multiple threads before my initialisation is done. So, I want to basically ensure that my logic code "waits" until initialisation is done.
This is my first cut.
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
synchronized(initialised) {
initStuff();
initialised.getAndSet(true);
initialised.notifyAll();
}
}
public void doStuff() {
synchronized(initialised) {
if (!initialised.get()) {
try {
initialised.wait();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
}
}
doOtherStuff();
}
}
I basically want to make sure this is going to do what I think it's going to do -- block doStuff until the initialised is true, and that I'm not missing a race condition where doStuff might get stuck on a Object.wait() that will never arrive.
Edit:
I have no control over the threads. And I want to be able to control when all of the initialisation is done, which is why doStuff() can't call initialise().
I used an AtomicBoolean as it was a combination of a value holder, and an object I could synchronize. I could have also simply had a "public static final Object lock = new Object();" and a simple boolean flag. AtomicBoolean conveniently gave me both. A Boolean can not be modified.
The CountDownLatch is exactly what I was looking for. I also considered using a Sempahore with 0 permits. But the CountDownLatch is perfect for just this task.
That's a strange mix of library and built-in concurrency controls. Something like this is much cleaner:
public class MyClass {
private static final CountDownLatch latch = new CountDownLatch(1);
public void initialise() {
initStuff();
latch.countDown();
}
public void doStuff() {
try {
latch.await();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
doOtherStuff();
}
}
A synchronized block will automatically block other threads. Just use a simple lock object + status variable:
public class MyClass {
private static boolean initialised;
private static final Object lockObject = new Object();
public void initialise() {
synchronized (lockObject) {
if (!initialised) {
initStuff();
initialised = true;
}
}
}
public void doStuff() {
initialise();
doOtherStuff();
}
}
The best may be to use a static initializer (as mentioned by SB):
public class MyClass {
public static void doInitialize() {
...
}
public void doStuff() {
doOtherStuff();
}
static {
doInitialize();
}
}
This will get executed once before any other code is allowed to be called. If you will always have to initialize anytime the class is used then there is no performance hit as the class will not be loaded until it is used. See the answers to this question for more details.
It this is right at startup, why not wait to start the other threads until the initialization is complete?
Also, you can do a thread-synchronized IsComplete boolean that is set to false until it is set to true by the initialization routine.
You're using AtomicBoolean always from inside a synchronized block. There's not much point to that since only one thread can access it. Atomic variables are intended for use in lock-free solutions - you can get and set the value as an uninterruptable unit.
I guess you are looking for a lock free solution once the intiialization has happened:
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
if (!intialized.get())
{
synchornized (this)
{
if (!initialized.getAndSet(true))
doInitialize();
}
}
}
public void doStuff() {
initialize();
doOtherStuff();
}
You could also do this with a simple volatile boolean which is actually a little more efficient than an AtomicBoolean.

Categories