java multithread performance on sync object - java

I am trying to test the multithreading performance with sync'ed object. However,
with 1 thread or with 16 threads the execution time is the same.
The rest of the code is here.
https://codeshare.io/5oJ6Ng
public void run() {
start = new Date().getTime();
System.out.println(start);
while (threadlist.size() < 9000) { //16 or more
// try{Thread.sleep(100);}catch (Exception f){}
Thread t = new Thread(new Runnable() {
public void run() {
while (add(1,3) < 1000000);
end = new Date().getTime();
System.out.println((end-start));
}
});
threadlist.add(t);
while( threadlist.iterator().hasNext()){
threadlist.iterator().next().start();
try{threadlist.iterator().next().join();}catch (Exception a){}
}
}
}

There are some issues with your code. First:
public void run() {
while (true) {
add(1, 3);
}
}
Those threads never stop working, I would suggest rewriting your logic to:
public void (run) {
while(add(1,3) < 1000000);
System.out.println("now 1000000");
}
public int add(int val1, int val2) {
synchronized (this) {
this.sum1 += val1;
this.sum2 += val2;
return this.sum1 + this.sum2;
}
}
}
You start the threads, but you never call join, eventually you will need to do that.
You are only creating 1 thread instead of the 16 that you wanted:
if (threadlist.size() < 1)
you want
if (threadlist.size() < 16)
Finally, do not expect any performance gain with this code, since you are synchronizing on the object:
synchronized (this){...}
So basically your add method is being run sequentially and not in parallel, since threads will wait on synchronized (this) and call only run on at the time inside your the block of code wrapped by the synchronized statement.
Try to measure your time by adding start = new Date().getTime(); before the parallel region, and end = new Date().getTime(); after.
You can simply your code to:
public void run() {
start = new Date().getTime();
System.out.println(start);
while (threadlist.size() < 16) {
Thread t = new Thread(() -> {
while (add(1,3) < 1);
System.out.println("now 1000000");
});
threadlist.add(t);
}
threadlist.forEach(Thread::start);
threadlist.forEach(thr-> {
try { thr.join();}
catch (InterruptedException e) { e.printStackTrace();}
});
end = new Date().getTime();
System.out.println("Time taken : "+(end-start));
public int add(int val1, int val2) {
synchronized (this) {
this.sum1 += val1;
this.sum2 += val2;
return this.sum1 + this.sum2;
}
}
}

You've significantly updated your code since #dreamcrash answered.
The current version has the following issues:
while( threadlist.iterator().hasNext()) {
threadlist.iterator().next().start();
try{threadlist.iterator().next().join();}catch (Exception a){}
}
This starts a thread and then will immediately sit around, twiddling its thumbs until that thread is completely done with its job, and will then fire up another thread. Therefore, you never more than 1 active thread at a time.
catch (Exception a){}
You're learning / debugging, and you do this? Oh dear. Don't. Don't ever write a catch block like that. Update your IDE or your muscle memory: The right "I dont want to think about exceptions right now" code is catch (Exception a) { throw new RuntimeException("Unhandled", a);}. To be clear, this isn't the problem, but this is such a bad habit, it needed to be called out.
synchronized (this) {
I really doubt if you fix the 'join' issue I mentioned earlier this will ever run any faster. This synchronized call is important, but it also causes so much blockage that you're likely to see zero actual benefit here.
More generally the calculation you are trying to speed up involves an accumulator.
accumulator is another word for 'parallelising is utterly impossible here, it is hopeless'.
The algorithm cannot involve accumulators if you want to parallellize it, which is what multithreading (at least, if the aim of the multiple threads is to speed things up) is doing. This algorithm cannot be made any faster with threads. period.
Usually algorithms can be rewritten to stop relying on accumulators. But this is clearly an exercise to see an effect, so, just find anything else, really. Don't lock on a single object for the entire calculation: Only one thread is ever actually doing work, all the 999 others are just waiting.

Related

Thread.sleep behaviour with non-volatile boolean variable

According to the JLS 17 specification section 17.3:
For example, in the following (broken) code fragment, assume that this.done is a non-volatile boolean field:
while (!this.done)
Thread.sleep(1000);
The compiler is free to read the field this.done just once, and reuse the cached value in each execution of the loop. This would mean that the loop would never terminate, even if another thread changed the value of this.done
I have tried to simulate this following example: 2 threads concurrently access the same boolean variable, the first thread using the shared boolean in while loop, and the second thread update the boolean value.
1.Code without Thread.sleep() inside the first thread:
public boolean done;
public void performTest() throws InterruptedException {
done = false;
new Thread(() -> {
System.out.println("Running Thread 1...");
int count = 0;
while (!done) {
count++;
}
System.out.println("Exiting thread...");
}).start();
Thread.sleep(100);
new Thread(() -> {
System.out.println("Thread 2 setting done to true");
done = true;
}).start();
}
-> This code would never terminated, because the done variable not declared as volatile
2.Now change the code to include Thread.sleep() inside while loop as mentioned in the JLS
public boolean done;
public void performTest() throws InterruptedException {
done = false;
new Thread(() -> {
System.out.println("Running Thread 1...");
int count = 0;
while (!done) {
count++;
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Exiting thread...");
}).start();
Thread.sleep(100);
new Thread(() -> {
System.out.println("Thread 2 setting done to true");
done = true;
}).start();
}
-> Now it successfully exists in the first thread.
So i am confused between this example and the JLS mentioned. Not sure what i am missing here.
Note: i also noticed that Venkat's also mentioned this example in one of his videos, and there is a blog post that explained this behavior, and it looks like there is something related to JIT optimization. What is really concerned me here is that this example is not like what is described in the JLS.
The reason that the code is broken in your example is because the JVM is free to use a cached version of done so that your loop would never end. When you have 'Thread.sleep()' in there, it is unlikely to happen, but it is still a possiblity. That means, you write some code and test it and it works great. Then you change an environment, or change a JVM and suddenly it is broken.
This is a poor benchmark, but it gives an idea.
public class VolatileTest implements Runnable{
boolean done = false;
public void run(){
long count = 0;
long start = System.nanoTime();
long end = Integer.MAX_VALUE;
while(!done){
count++;
if(count == end){
break;
}
//try{ Thread.sleep(0); } catch (Exception e){ break;}
}
System.out.println( System.nanoTime() - start + " with " + count + " iterations");
}
public static void main(String[] args) throws Exception{
VolatileTest vt = new VolatileTest();
new Thread(vt).start();
Thread.sleep(500);
vt.done = true;
}
}
Now there are 3 cases. 1st as written without any sleep/volatile.
650503733 with 2147483647 iterations
It took 650ms to complete Integer.MAX_VALUE iterations. note sometimes this
finishes faster than the 500ms I wait.
2nd case, volatile done.
499923823 with 1091070867 iterations
Now it never completes before vt.done is set to true.
3rd case. non-volatile with Thread.sleep
499905166 with 3031374 iterations
With the volatile version is 300 times faster than the Thread.sleep version. The non-volatile version is more intermittent in how fast it is but it is the fastest. I suspect due to when the JIT decides to cache done it gets a speed boost so to speak.
I'm not sure how to verify when it decides to cache the done variable, but I think that why JMH is necessary for these types of micro benchmarks.

Multithread Binary Semaphore's: Alternating Outputs

The goal is to have String of output's consisting of W's, X's ,y's
and z's.
W and X should alternate and W must always be ahead of X.
y and z must alternate with y always ahead of z.
The total of y's and z's must be less than the number of W's at any given point in the output.
My program so far satisfies the first two points but I'm having trouble with the last one. Also, I very new to semaphore's and want to know if the code I've implemented follows good practices. For example, I had originally set the initial value of my binary semaphores to 0,1,2,3 but changed it to 0,1,0,1 in order to satisfy the second condition.
public class BinarySemaphore extends Semaphore{
public BinarySemaphore(int initial) {
value = (initial>0) ? 1 : 0;
}
public synchronized void P() throws InterruptedException {
while (value==0) {
wait();
}
value = 0;
}
public synchronized void V() {
value = 1;
notify();
}
}
public class ProcessW extends App implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1 + (int) (Math.random() * 500));
bsX.P();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.print("W");
bsW.V();
}
}
}
public class ProcessX extends App implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1 + (int) (Math.random() * 500));
bsW.P();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.print("X");
bsX.V();
}
}
}
public class ProcessY extends App implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1 + (int) (Math.random() * 800));
bsZ.P();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.print("y");
bsY.V();
}
}
}
public class ProcessZ extends App implements Runnable{
public void run() {
while (true) {
try {
Thread.sleep(1 + (int) (Math.random() * 800));
bsY.P();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.print("z");
bsZ.V();
}
}
}
public class App {
protected static final BinarySemaphore bsW = new BinarySemaphore(
0);
protected static final BinarySemaphore bsX = new BinarySemaphore(
1);
protected static final BinarySemaphore bsY = new BinarySemaphore(
0);
protected static final BinarySemaphore bsZ = new BinarySemaphore(
1);
public static void main(String[] args) throws Exception {
Thread W = new Thread(new ProcessW());
Thread X = new Thread(new ProcessX());
Thread Y = new Thread(new ProcessY());
Thread Z = new Thread(new ProcessZ());
W.start();
X.start();
Y.start();
Z.start();
Thread.sleep(3000);
System.out.println("");
System.exit(0);
}
}
Here is an example of what my program is currently outputting:
WXWyzXWXWXyzyWXWXzyzWXyzWXyzWX
Your goal is not defined very well because you didn't write what means are you required to use to achieve the goal. For instance, a program that always prints "WXyzWX" satisfies your question. But I'll assume you specifically want to use four threads each printing its own letter, and you want to use Semaphores for this.
Semaphores are used to manage a number of "permissions" between different threads. A thread can semaphore.acquire() a permission and semaphore.release() it after doing its job. If no permissions are available at the moment of calling acquire(), the thread waits until some other thread releases a permission. See documentation for details.
You can use Semaphores for your purpose, but before that I have to explain what "fairness" means in terms of multithreading. By default, the Semaphore (and all other Java concurrent stuff) is "unfair". This means that when a permission is released, it will be given to any of the threads that are waiting for one, considering the overall performance first. On the other hand, a "fair" Semaphore will always give a newly available permission to the thread that has been waiting for one for the longest time. This practically orders the threads as if in a queue. In general, fair structures work slower, but in our case this fairness is very useful.
Now to the idea. You can think of your letter ordering in a following way: to write X, a thread needs a permission that will only be available to it after another thread writes W, and then to write W you will need a permission from X thread. So you can use a semaphore for these two threads, with each thread acquiring and releasing a permission from the semaphore before and after printing the letter. And its fairness guarantees that W and X will always be alternating (don't forget that by default semaphores are unfair, you have to specify a flag in its constructor in order to make it fair). You should also make sure which thread acquires the permission first, or else you will get X always ahead of W.
You can make a similar trick to alternate y and z, but now you have to guarantee your third condition. This is also doable using a semaphore: to write a y or a z, you need a permission that can only be acquired after some W-s were written. I'm going to make you think this one through by yourself. Maybe a nice idea would be to randomly decide whether to release a permission or not, but no details here :)
I must mention that this is by far not the only way to accomplish your task, and also semaphores may be not the best tool to use in here. (I don't think a specific best one exists though.)
And now some extra comments on your code:
What exactly is your purpose of extending the java Semaphore? You never use any of its methods. You can just delete that 'extends' if you want to use this code.
To generate a random value from 0 to N, there is a nextInt(N) method in java.util.Random class. It suits your purposes better.
InterruptedException is one of the few ones that can be safely ignored most of the times (unless you know what it means and want to use it). I mention it because in case it is thrown, your output is going to be mixed up with letters and exceptions.
You simply create a thread, start it and then never access it. In this case, you can simplify your lines to new Thread(new ProcessW()).start() without even creating a variable.
P() and V() are terrible names for methods - I can barely understand what they are supposed to do.
What is the purpose of your BinarySemaphore fields in App class being protected? Did you mean private?
You're stopping all of your threads by calling System.exit(0). This way you cannot make a difference which threads to stop and which not to, as well as being unable to do anything after stopping the threads. A simple solution would be to create a volatile boolean isRunning = true; visible to all threads (do you know what volatile is?), replace while(true) to while(isRunning) and instead of calling System.exit() just do isRunning = false. Or else use the interruption mechanism (again, if you know what it is).

Thread Signalling Sequence

In the below code I have implemented inter Thread communication using wait() -notify() and it is giving me expected output.
expected Output : 123456789 Actual output : 123456789
My question is , is there any guarantee that always 'Main Thread' will get the first chance to execute, since Thread scheduling depends on jvm. And if 'child thread' gets the first chance, the notify() signal will miss and the 'main Thread ' will wait forever. How can I confirm that 'Main thread' will execute first always. Also please confirm if the below code can be improved.
package com.test.Thread;
public class ThreadExample1 {
public static void main(String[] args) throws InterruptedException{
ThreadChild1 lockingObj = new ThreadChild1();
lockingObj .start();
synchronized(lockingObj ){
for(int i=1;i<10;i++){
System.out.println("Main "+i);
}
lockingObj.wait();
System.out.println("Main got notified");
}
}
}
class ThreadChild1 extends Thread{
public void run(){
synchronized(this){
for(int i=1;i<10;i++){
System.out.println("Child "+i);
}
this.notify();
}
}
}
Your code is wrong for the reason that you mentioned yourself: you can't be sure which thread goes first.
There are other things that could go wrong - wait can wake up without a notify.
You can read about it in the Javadoc for the wait method, which also explains what you should do:
As in the one argument version, interrupts and spurious wakeups are
possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
In your code, you can solve it with a boolean variable that expresses the condition "I was notified":
public class ThreadExample1 {
public static void main(String[] args) throws InterruptedException {
ThreadChild1 lockingObj = new ThreadChild1();
lockingObj.start();
synchronized (lockingObj) {
for(int i = 1; i < 10; i++) {
System.out.println("Main " + i);
}
while (!lockingObj.haveNotified) {
lockingObj.wait();
}
System.out.println("Main got notified");
}
}
}
class ThreadChild1 extends Thread{
private boolean haveNotified;
public void run(){
synchronized (this) {
for (int i = 1; i < 10; i++) {
System.out.println("Child " + i);
}
haveNotified = true;
this.notify();
}
}
}
While this works correctly on your system, it is not a guranty as your suspicion might become true on a different system. Threading behavior is verry difficult/impossible to predict. Therefore I like to think in worst case scenarios, and if I can come up with a possible breaking situation (as you just described one) I simply redesign to make sure it will work.
A nice trick to test your code is to suspend/pause threads on critical moments by either adding a breakpoint in your IDE, adding a verry time consuming task/call if possible (not failsafe), or by fysically pausing the thread(not always ideal). Besides Im sure there is are libraries to expand on this type of tesing.
I hope this helps you a bit in the right direction.

Are unsynchronized reads (combined with synchronized writes) eventually consistent

I have a use case with many writer threads and a single reader thread. The data being written is an event counter which is being read by a display thread.
The counter only ever increases and the display is intended for humans, so the exact point-in-time value is not critical. For this purpose, I would consider a solution to be correct as long as:
The value seen by the reader thread never decreases.
Reads are eventually consistent. After a certain amount of time without any writes, all reads will return the exact value.
Assuming writers are properly synchronized with each other, is it necessary to synchronize the reader thread with the writers in order to guarantee correctness, as defined above?
A simplified example. Would this be correct, as defined above?
public class Eventual {
private static class Counter {
private int count = 0;
private Lock writeLock = new ReentrantLock();
// Unsynchronized reads
public int getCount() {
return count;
}
// Synchronized writes
public void increment() {
writeLock.lock();
try {
count++;
} finally {
writeLock.unlock();
}
}
}
public static void main(String[] args) {
List<Thread> contentiousThreads = new ArrayList<>();
final Counter sharedCounter = new Counter();
// 5 synchronized writer threads
for(int i = 0; i < 5; ++i) {
contentiousThreads.add(new Thread(new Runnable(){
#Override
public void run() {
for(int i = 0; i < 20_000; ++i) {
sharedCounter.increment();
safeSleep(1);
}
}
}));
}
// 1 unsynchronized reader thread
contentiousThreads.add(new Thread(new Runnable(){
#Override
public void run() {
for(int i = 0; i < 30; ++i) {
// This value should:
// +Never decrease
// +Reach 100,000 if we are eventually consistent.
System.out.println("Count: " + sharedCounter.getCount());
safeSleep(1000);
}
}
}));
contentiousThreads.stream().forEach(t -> t.start());
// Just cleaning up...
// For the question, assume readers/writers run indefinitely
try {
for(Thread t : contentiousThreads) {
t.join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void safeSleep(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
//Don't care about error handling for now.
}
}
}
There is no guarantee that the readers would ever see an update to the count. A simple fix is to make count volatile.
As noted in another answer, in your current example, the "Final Count" will be correct because the main thread is joining the writer threads (thus establishing a happens-before relationship). however, your reader thread is never guaranteed to see any update to the count.
JTahlborn is correct, +1 from me. I was rushing and misread the question, I was assuming wrongly that the reader thread was the main thread.
The main thread can display the final count correctly due to the happens-before relationship:
All actions in a thread happen-before any other thread successfully returns from a join on that thread.
Once the main thread has joined to all the writers then the counter's updated value is visible. However, there is no happens-before relationship forcing the reader's view to get updated, you are at the mercy of the JVM implementation. There is no promise in the JLS about values getting visible if enough time passes, it is left open to the implementation. The counter value could get cached and the reader could possibly not see any updates whatsoever.
Testing this on one platform gives no assurance of what other platforms will do, so don't think this is OK just because the test passes on your PC. How many of us develop on the same platform we deploy to?
Using volatile on the counter or using AtomicInteger would be good fixes. Using AtomicInteger would allow removing the locks from the writer thread. Using volatile without locking would be OK only in a case where there is just one writer, when two or more writers are present then ++ or += not being threadsafe will be an issue. Using an Atomic class is a better choice.
(Btw eating the InterruptedException isn't "safe", it just makes the thread unresponsive to interruption, which happens when your program asks the thread to finish early.)

Wait x seconds or until a condition becomes true

How to wait x seconds or until a condition becomes true? The condition should be tested periodically while waiting. Currently I'm using this code, but there should be a short function.
for (int i = 10; i > 0 && !condition(); i--) {
Thread.sleep(1000);
}
Assuming you want what you asked for, as opposed to suggestions for redesigning your code, you should look at Awaitility.
For example, if you want to see if a file will be created within the next 10 seconds, you do something like:
await().atMost(10, SECONDS).until(() -> myFile.exists());
It's mainly aimed at testing, but does the specific requested trick of waiting for an arbitrary condition, specified by the caller, without explicit synchronization or sleep calls. If you don't want to use the library, just read the code to see the way it does things.
Which, in this case, comes down to a similar polling loop to the question, but with a Java 8 lambda passed in as an argument, instead of an inline condition.
I didn't find a solution in the JDK. I think this feature should be added to the JDK.
Here what I've implemented with a Functional Interface:
import java.util.concurrent.TimeoutException;
import java.util.function.BooleanSupplier;
public interface WaitUntilUtils {
static void waitUntil(BooleanSupplier condition, long timeoutms) throws TimeoutException{
long start = System.currentTimeMillis();
while (!condition.getAsBoolean()){
if (System.currentTimeMillis() - start > timeoutms ){
throw new TimeoutException(String.format("Condition not met within %s ms",timeoutms));
}
}
}
}
Have you thought about some classes from java.util.concurrent - for example a BlockingQueue?
You could use:
BlockingQueue<Boolean> conditionMet = new BlockingQueue<Boolean>;
conditionMet.poll(10,TimeUnit.SECONDS);
And then in the code that changes your condition do this:
conditionMet.put(true);
EDIT:
Another example form java.util.concurrent may be CountDownLatch:
CountDownLatch siteWasRenderedLatch = new CountDownLatch(1);
boolean siteWasRendered = siteWasRenderedLatch.await(10,TimeUnit.SECONDS);
This way you'll wait 10 seconds or until the latch reaches zero. To reach zero all you have to do is:
siteWasRenderedLatch.countDown();
This way you won't need to use locks which would be needed in Condition examples presented by #Adrian. I think it's just simpler and straight-forward.
And if you don't like the naming 'Latch' or 'Queue' you can always wrap it into your own class called i.e. LimitedTimeCondition:
public class LimitedTimeCondition
{
private CountDownLatch conditionMetLatch;
private Integer unitsCount;
private TimeUnit unit;
public LimitedTimeCondition(final Integer unitsCount, final TimeUnit unit)
{
conditionMetLatch = new CountDownLatch(1);
this.unitsCount = unitsCount;
this.unit = unit;
}
public boolean waitForConditionToBeMet()
{
try
{
return conditionMetLatch.await(unitsCount, unit);
}
catch (final InterruptedException e)
{
System.out.println("Someone has disturbed the condition awaiter.");
return false;
}
}
public void conditionWasMet()
{
conditionMetLatch.countDown();
}
}
And the usage would be:
LimitedTimeCondition siteRenderedCondition = new LimitedTimeCondition(10, TimeUnit.SECONDS);
//
...
//
if (siteRenderedCondition.waitForConditionToBeMet())
{
doStuff();
}
else
{
System.out.println("Site was not rendered properly");
}
//
...
// in condition checker/achiever:
if (siteWasRendered)
{
condition.conditionWasMet();
}
Have a look at Condition.
Conditions (also known as condition queues or condition variables)
provide a means for one thread to suspend execution (to "wait") until
notified by another thread that some state condition may now be true.
Because access to this shared state information occurs in different
threads, it must be protected, so a lock of some form is associated
with the condition. The key property that waiting for a condition
provides is that it atomically releases the associated lock and
suspends the current thread, just like Object.wait.
A Condition instance is intrinsically bound to a lock. To obtain a
Condition instance for a particular Lock instance use its
newCondition() method.
EDIT:
Related question Sleep and check until condition is true
Related question is there a 'block until condition becomes true' function in java?
You may want to use something like the code below (where secondsToWait holds the maximum number of seconds you want to wait to see if the condition() turns true. The varialbe isCondetionMet will contain true if the condition was found, or false if the code timed out waiting for the condition.
long endWaitTime = System.currentTimeMillis() + secondsToWait*1000;
boolean isConditionMet = false;
while (System.currentTimeMillis() < endWaitTime && !isConditionMet) {
isConditionMet = condition();
if (isConditionMet) {
break;
} else {
Thread.sleep(1000);
}
}
I'm using the following adaptation of the original question's solution:
public class Satisfied {
public static boolean inTime(Callable<Boolean> condition, int timeoutInSecs) {
int count;
try {
for (count = 1; count < timeoutInSecs * 20 && !condition.call(); count++)
Thread.sleep(50);
return (count < timeoutInSecs * 20);
} catch (Exception e) {
throw new AssertionError(e.getMessage());
}
}
}
When used in testing, it appears like this:
assertThat(Satisfied.inTime(() -> myCondition(), 5)).isTrue();
Using await Awaitility:
Awaitility.with().pollDelay(1000, TimeUnit.MILLISECONDS).await().until(() -> true);

Categories

Resources