Object Lock for unique values - java

Hi I have one synchronized method which returns ms. Can anyone tell whether where each object will get the unique value in below code.
public static synchronized Long generateIdforDCR()
{
int val= return System.nanoTime();
}
Call will be in another class like
forloop 1... 1000
{
ClassName cn=new ClassName();
cn.generateIdforDCR();
}
Will i get unique value always.

No - there's no guarantee that each call will return a different value. It's not inconceivable that the call (including synchronization) could take less time than the granularity of the internal clock used for nanoTime(). (Indeed, I can see this happen on my laptop.)
It sounds like you should just be using an AtomicLong instead:
private static final AtomicLong counter = new AtomicLong();
public static Long generateIdforDCR() {
return counter.incrementAndGet();
}
That will give you a unique number (if you call it fewer than 264 times) within that run. If you need it to be unique within a larger scope (e.g. across multiple sequential runs, or potentially multiple concurrent runs of different processes) then you'll need a slightly different approach.

Related

Count number of instances of a class in multi-threading environment?

I am trying to count how many instances of a class generated during the run time of a process under multi-threading environment. The way how I do it is to increase a static counter in the constructor by looking at this post:
How to Count Number of Instances of a Class
So in multi-threading environment, here is how i define the class:
class Television {
private static volatile int counter = 0;
public Television(){
counter ++;
}
}
However, I am not sure whether there is a potential bug with the code above since I think constructor in java does not imply synchronization and counter++ is not atomic so if two threads are creating instances simultaneously, is the code a bug somehow? but I am not quite sure yet.
There is a bug in this code (specifically, a race condition), because the read of counter and write to counter aren't atomically executed.
In other words, two threads can read the same value of counter, increment that value, and then write the same value back to the variable.
Thread 1 Thread 2
======== ========
Read 0
Read 0
Increment
Increment
Write 1
Write 1
So the value would be 1, not 2, afterwards.
Use AtomicInteger and AtomicInteger.incrementAndGet() instead.
As counter++ is NOT atomic, you can replace it with JDK's AtomicInteger which is threadsafe.
You can AtomicInteger's use getAndIncrement() method as shown below:
class Television {
private static final AtomicInteger counter = new AtomicInteger();
public Television(){
counter.getAndIncrement();
}
}
An AtomicInteger is used in applications such as atomically
incremented counters, and cannot be used as a replacement for an
Integer.
You can look here
There are two ways here to bypass the underlying "++ on int" not being an atomic operation:
A) as others suggested, use AtomicInteger
B) introduce a common LOCK that all ctors can be using to sync on; like:
private final static Object LOCK = new Object();
public Television() {
synchronized (LOCK) {
counter++;
}

Know which thread goes to which processor in a Java ForkJoinPool in Apache Spark?

Goal: To know, as I fork off a thread, which processor it's going to land on. Is that possible? Regardless of whether the underlying approach is valid, is there a good answer to that narrow question? Thanks.
(Right now I need to make a copy of one of our classes for each thread, write to it in that thread and merge them all later. Using a synchronized approach is not possible because my Java expert boss thinks it's a bad idea, and after a lot of discussion I agree. If I knew which processor each thread would land on, I would only need to make as many copies of that class as there are processors.)
We use Apache Spark to get our jobs spread across a cluster, but in our application is makes sense to run one big executor and then do some multi-threading of our own out on each machine in the cluster.
I could save a lot of deep copying if I could know which processor a thread is being sent to, is that possible? I threw in our code but it's probably more of a conceptual question:
When I get down to the "do task" part of compute(), can I know which processor it's running on?
public class TholdExecutor extends RecursiveTask<TholdDropEvaluation> {
final static Logger logger = LoggerFactory.getLogger(TholdExecutor.class);
private List<TholdDropResult> partitionOfN = new ArrayList<>();
private int coreCount;
private int desiredPartitionSize; // will be updated by whatever is passed into the constructor per-chromosome
private TholdDropEvaluation localDropEvaluation; // this DropEvaluation
private TholdDropResult mSubI_DR;
public TholdExecutor(List<TholdDropResult> subsetOfN, int cores, int partSize, TholdDropEvaluation passedDropEvaluation, TholdDropResult mDrCopy) {
partitionOfN = subsetOfN;
coreCount = cores;
desiredPartitionSize = partSize;
// the TholdDropEvaluation needs to be a copy for each thread? It can't be the same one passed to threads ... so ...
TholdDropEvaluation localDropEvaluation = makeDECopy(passedDropEvaluation); // THIS NEEDS TO BE A DEEP COPY OF THE DROP EVAL!!! NOT THE ORIGINAL!!
// we never modify the TholdDropResult that is passed in, we just need to read it all on the same JVM/worker, so
mSubI_DR = mDrCopy; // this is purely a reference and can point to the passed in value (by reference, right?)
}
// this makes a deep copy of the TholdDropEvaluation for each thread, we copy the SharingRun's startIndex and endIndex only,
// as LEG events will be calculated during the subsequent dropComparison. The constructor for TholdDropEvaluation must set
// LEG events to zero.
private void makeDECopy(TholdDropEvaluation passedDropEvaluation) {
TholdDropEvaluation tholdDropEvaluation = new TholdDropEvaluation();
// iterate through the SharingRuns in the SharingRunList from the TholdDropEval that was passed in
for (SharingRun sr : passedDropEvaluation.getSharingRunList()) {
SharingRun ourSharingRun = new SharingRun();
ourSharingRun.startIndex = sr.startIndex;
ourSharingRun.endIndex = sr.endIndex;
tholdDropEvaluation.addSharingRun(ourSharingRun);
}
return tholdDropEvaluation
}
#Override
protected TholdDropEvaluation compute() {
int simsToDo = partitionOfN.size();
UUID tag = UUID.randomUUID();
long computeStartTime = System.nanoTime();
if (simsToDo <= desiredPartitionSize) {
logger.debug("IN MULTI-THREAD compute() --- UUID {}:Evaluating partitionOfN sublist length", tag, simsToDo);
// job within size limit, do the task and return the completed TholdDropEvaluation
// iterate through each TholdDropResult in the sub-partition and do the dropComparison to the refernce mSubI_DR,
// writing to the copy of the DropEval in tholdDropEvaluation
for (TholdDropResult currentResult : partitionOfN) {
mSubI_DR.dropComparison(currentResult, localDropEvaluation);
}
} else {
// job too large, subdivide and call this recursively
int half = simsToDo / 2;
logger.info("Splitting UUID = {}, half is {} and simsToDo is {}", tag, half, simsToDo );
TholdExecutor nextExec = new TholdExecutor(partitionOfN.subList(0, half), coreCount, desiredPartitionSize, tholdDropEvaluation, mSubI_DR);
TholdExecutor futureExec = new TholdExecutor(partitionOfN.subList(half, simsToDo), coreCount, desiredPartitionSize, tholdDropEvaluation, mSubI_DR);
nextExec.fork();
TholdDropEvaluation futureEval = futureExec.compute();
TholdDropEvaluation nextEval = nextExec.join();
tholdDropEvaluation.merge(futureEval);
tholdDropEvaluation.merge(nextEval);
}
logger.info("{} Compute time is {} ns",tag, System.nanoTime() - computeStartTime);
// NOTE: this was inside the else block in Rob's example, but don't we want it outside the block so it's returned
// whether
return tholdDropEvaluation;
}
}
Even if you could figure out where a thread would run initially there's no reason to assume it would live on that processor/core for the rest of its life. In all probability for any task big enough to be worth the cost of spawning a thread it won't, so you'd need to control where it ran completely to offer that level of assurance.
As far as I know there's no standard mechanism for controlling mappings from threads to processor cores inside Java. Typically that's known as "thread affinity" or "processor affinity". On Windows and Linux for example you can control that using:
Windows: SetThreadAffinityMask
Linux: sched_setaffinity or pthread_setaffinity_np
so in theory you could write some C and JNI code that allowed you to abstract this enough on the Java hosts you cared about to make it work.
That feels like the wrong solution to the real problem you seem to be facing, because you end up withdrawing options from the OS scheduler, which potentially doesn't allow it to make the smartest scheduling decisions causing total runtime to increase. Unless you're pushing an unusual workload and modelling/querying processor information/topology down to the level of NUMA and shared caches it ought to do a better job of figuring out where to run threads for most workloads than you could. Your JVM typically runs a large number of additional threads besides just the ones you explicitly create from after main() gets called. Additionally I wouldn't like to promise anything about what the JVM you run today (or even tomorrow) might decide to do on its own about thread affinity.
Having said that it seems like the underlying problem is that you want to have one instance of an object per thread. Typically that's much easier than predicting where a thread will run and then manually figuring out a mapping between N processors and M threads at any point in time. Usually you'd use "thread local storage" (TLS) to solve this problem.
Most languages provide this concept in one form or another. In Java this is provided via the ThreadLocal class. There's an example in the linked document given:
public class ThreadId {
// Atomic integer containing the next thread ID to be assigned
private static final AtomicInteger nextId = new AtomicInteger(0);
// Thread local variable containing each thread's ID
private static final ThreadLocal<Integer> threadId =
new ThreadLocal<Integer>() {
#Override protected Integer initialValue() {
return nextId.getAndIncrement();
}
};
// Returns the current thread's unique ID, assigning it if necessary
public static int get() {
return threadId.get();
}
}
Essentially there are two things you care about:
When you call get() it returns the value (Object) belonging to the current thread
If you call get in a thread which currently has nothing it will call initialValue() you implement, which allows you to construct or obtain a new object.
So in your scenario you'd probably want to deep copy the initial version of some local state from a read-only global version.
One final point of note: if your goal is to divide and conquer; do some work on lots of threads and then merge all their results to one answer the merging part is often known as a reduction. In that case you might be looking for MapReduce which is probably the most well known form of parallelism using reductions.

synchronized on an Object seems like it's not synchronized

I run a program which contains the following classes (not only, but these are the relevant ones for the question)
Under Results class I have a synchronized LinkedHashMap such as:
private static Map<Integer,Result> resultsHashMap=Collections.synchronizedMap(new LinkedHashMap<Integer, Result>());
and a getter method:
public static Map<Integer,Result> getResultsHashMap() {
return resultsHashMap;
}
As well I have inside my Result class a constructor with this synchronized code:
public Result(){
synchronized (Lock.lock) {
uniqueIdResult++;
}
}
and a synchronized getter method as such:
public static int getUniqueIdResult() {
synchronized (Lock.lock) {
return uniqueIdResult;
}
}
the uniqueIdResult is defined as following:
private static int uniqueIdResult=0;
Also I have a Lock class consists this Object:
public static final Lock lock=new Lock();
Now, this is the important issue i'm after. In my program I have the next 2 lines, which are creating a Result and putting it into the HashMap
Result result = new Result();
Results.getResultsHashMap().put(Result.getUniqueIdResult(), result);
I try to run my program with different number of Threads. When it is being run with 1 thread the output is as I expect it to be (specifically, but not necessarily important, Results.resultsHashMap contains 433 keys, which is what should be, and the keys are starting from 1).
But when I run it with different number of Threads, it gives a different output. For example running with 6 Threads gives a different number of keys each time, sometimes 430, sometimes 428, sometimes 427, etc.. and the starting key is not always related to the total number of keys (e.g total_number_of_keys-starting_key_number+1, which seemed to me in the beginning to be some pattern, but realized it's not)
The iteration is like this:
int counterOfResults=0;
for (Integer key : Results.getResultsHashMap().keySet()) {
System.out.println(key + " " + Results.getResultsHashMap().get(key));
counterOfResults++;
}
System.out.println(counterOfResults);
Also when synchronizing the getter method for getting the hashMap, without synchronization of the Result creation and the insertion to the hashMap, the output with multiple threads gives wrong output.
Also, when synchronizing only one of the lines (creation of Result and putting into hashMap), the output is not coherent under multiple Threads.
However when I synchronize both these lines (the creation of Result and putting into the map) like so:
Result result;
synchronized (Lock.lock) {
result = new Result(currentLineTimeNationalityNameYearofbirth.getName(),currentLineTimeNationalityNameYearofbirth.getTime(),citycompetionwas,date,distance,stroke,gender,kindofpool);
Results.getResultsHashMap().put(Result.getUniqueIdResult(), result);
}
the output is perfect, no matter how many Threads I use.
Also, I will note that the output is being printed only after all Threads have finished, by using join method for all Threads created.
So my question is:
As far as I know, before synchronizing the 2 lines (creating Result and puting into hashMap) all of my critical sections ,e.g, changing and getting the uniqueIdResult, getting the resultsHashMap (as I mentioned, I tried synchronizing this getter method also) are being synchronized on the same object, plus I put a further safe approach when puting the hashMap with Collections.synchronizedMap, which,as far as I know, should make the hashMap thread-safe.
Why then the output is not as I expect it to be? Where is there a safety problem?
There's no exclusion around these lines:
Result result = new Result();
Results.getResultsHashMap().put(Result.getUniqueIdResult(), result);
If you have 4 threads, they might all execute the first line (which will increment the uniqueIdResult variable four times), and then all execute the second line (at which point they will all see the same return value from getUniqueIdResult()). That explains how your keys could start at 4 when you have 4 (or more) threads.
Because you have multiple threads potentially (and unpredictably) storing to the same key, you also end up with a variable number of entries in your map.
You should probably remove the increment from the Result class constructor and instead do it in the getUniqueIdResult method:
public static int getUniqueIdResult() {
synchronized (Lock.lock) {
return ++uniqueIdResult;
}
}
(Having done that, there is no longer any need to create instances of Result at all).

Thread safety with Java static inner class field

I have a class something like this:
public class Outer {
public static final TaskUpdater TASK_UPDATER = new TaskUpdater() {
public void doSomething(Task task) {
//uses and modifies task and some other logic
}
};
public void taskRelatedMethod() {
//some logic
TASK_UPDATER.doSomething(new Task());
//some other logic
}
}
I've noticed some strange behaviour when running this in a multi-threaded environment that I can't reproduce locally, and I suspect it's a threading issue. Is it possible for two instances of Outer to somehow interfere with each other by both calling doSomething on TASK_UPDATER? Each will be passing a difference instance of Task into the doSomething method.
Is it possible for two instances of Outer to somehow interfere with each other by both calling doSomething on TASK_UPDATER?
The answer is "it depends". Any time you have multiple threads sharing the same object instances, you may have concurrency issues. In your case, you have multiple instances of Outer sharing the same static TaskUpdater instance. This in itself is not a problem however if TaskUpdater has any fields, they will be shared by the threads. If the threads make any changes to those fields in any way then data synchronization needs to happen and possible blocking around critical code sections. If the TaskUpdater is only reading and operating on the Task argument, which seems to be per Outer instance, then there is no problem.
For example, you could have a task updater like:
public static final TaskUpdater TASK_UPDATER = new TaskUpdater() {
public void doSomething(Task task) {
int total = 0;
for (Job job : task.getJobs() {
total += job.getSize();
}
task.setTotalSize(total);
}
};
In this case, the task is only changing the Task instance passed in. It can use local variables without a problem because those are on the stack and now shared between threads. This is thread safe.
However consider this updater:
public static final TaskUpdater TASK_UPDATER = new TaskUpdater() {
private long total = 0;
public void doSomething(Task task) {
for (Job job : task.getJobs() {
// race condition and memory synchronization issues here
total += job.getSize();
}
}
public long getTotal() {
return total;
}
};
In this case, both threads will be updating the same total field on the shard TaskUpdater. This is not thread safe since you have race conditions around the += (since it is 3 operations: get, plus, set) as well as memory synchronization issues. One thread may have a cached version of total which is 5 which it increments to 6 but another thread has already incremented its cached version of total to 10.
When threads share common fields you need to protect those operations and worry about synchronization in terms of mutex access and memory publishing. In this case, making total be an AtomicLong will be in order.
private AtomicLong total = new AtomicLong(0);
...
total.addAndGet(job.getSize());
AtomicLong wraps a volatile long so the memory is published appropriately to all threads and it has code that does atomic test/set operations which removes the race conditions.

Is synchronization needed while reading if no contention could occur

Consider code sniper below:
package sync;
public class LockQuestion {
private String mutable;
public synchronized void setMutable(String mutable) {
this.mutable = mutable;
}
public String getMutable() {
return mutable;
}
}
At time Time1 thread Thread1 will update ‘mutable’ variable. Synchronization is needed in setter in order to flush memory from local cache to main memory.
At time Time2 ( Time2 > Time1, no thread contention) thread Thread2 will read value of mutable.
Question is – do I need to put synchronized before getter? Looks like this won’t cause any issues - memory should be up to date and Thread2’s local cache memory should be invalidated&updated by Thread1, but I’m not sure.
Rather than wonder, why not just use the atomic references in java.util.concurrent?
(and for what it's worth, my reading of happens-before does not guarantee that Thread2 will see changes to mutable unless it also uses synchronized ... but I always get a headache from that part of the JLS, so use the atomic references)
It will be fine if you make mutable volatile, details in the "cheap read-write lock"
Are you absolutely sure that the getter will be called only after the setter is called? If so, you don't need the getter to be synchronized, since concurrent reads do not need to synchronized.
If there is a chance that get and set can be called concurrently then you definitely need to synchronize the two.
If you worry so much about the performance in the reading thread, then what you do is read the value once using proper synchronization or volatile or atomic references. Then you assign the value to a plain old variable.
The assign to the plain variable is guaranteed to happen after the atomic read (because how else could it get the value?) and if the value will never be written to by another thread again you are all set.
I think you should start with something which is correct and optimise later when you know you have an issue. I would just use AtomicReference unless a few nano-seconds is too long. ;)
public static void main(String... args) {
AtomicReference<String> ars = new AtomicReference<String>();
ars.set("hello");
long start = System.nanoTime();
int runs = 1000* 1000 * 1000;
int length = test(ars, runs);
long time = System.nanoTime() - start;
System.out.printf("get() costs " + 1000*time / runs + " ps.");
}
private static int test(AtomicReference<String> ars, int runs) {
int len = 0;
for (int i = 0; i < runs; i++)
len = ars.get().length();
return len;
}
Prints
get() costs 1219 ps.
ps is a pico-second, with is 1 millionth of a micro-second.
This probably will never result in incorrect behavior, but unless you also guarantee the order that the threads startup in, you cannot necessarily guarantee that the compiler didn't reorder the read in Thread2 before the write in Thread1. More specifically, the entire Java runtime only has to guarantee that threads execute as if they were run in serial. So, as long as the thread has the same output running serially under optimizations, the entire language stack (compiler, hardware, language runtime) can do
pretty much whatever it wants. Including allowing Thread2 to cache the the result of LockQuestion.getMutable().
In practice, I would be very surprised if that ever happened. If you want to guarantee that this doesn't happen, have LockQuestion.mutable be declared as final and get initialized in the constructor. Or use the following idiom:
private static class LazySomethingHolder {
public static Something something = new Something();
}
public static Something getInstance() {
return LazySomethingHolder.something;
}

Categories