As shown in example below, once lock is taken on an object in call method, there is no need for further methods to have synchronized keyword.
public class Prac
{
public static void main(String[] args)
{
new Prac().call();
}
private synchronized void call()
{
further();
}
private synchronized void further()
{
oneMore();
}
private synchronized void oneMore()
{
// do something
}
}
But, if I still add synchronized keyword to further and onceMore, how will performance be impacted? Or not impacted at all?
EDIT : Does it add costs of checking(after encountering synchronized keyword) if it has lock or lock is required? Internally does this checking adds overhead?
EDIT : application will not have one thread only, this code here is just sample code. may be replace main with run method
The performance will not be impacted. Acquiring a lock, which is already acquired costs nothing. This technique is called biased locking. By default biased locking is switched on. That's why single thread applications are not impacted by calling synchronized methods.
Java SE 6 Performance White Paper:
An object is "biased" toward the thread which first acquires its monitor via a monitorenter bytecode or synchronized method invocation; subsequent monitor-related operations can be performed by that thread without using atomic operations resulting in much better performance, particularly on multiprocessor machines.
synchronization mechanism make methods a little bit slower so try to not synchronize method if you have only one thread
Since JDK 7 HotSpot JVM is capable of optimizing such code by eliminating nested locks.
The optimization is called -XX:+EliminateNestedLocks and is turned on by default.
The redundant locks are removed during JIT-compilation, so there is no run-time overhead even to check if the lock is already taken. However this optimization works only when monitor object is static final or when locking this object.
I modified the benchmark according to the comment below. In this benchmark, acquiring the lock multiple times, occasionally takes less time than acquire_once, but I think this is because of background threads like gc and jit
public class Benchmark {
final int count = 10000;
boolean the_bool = false; // prevent no-op optimization inside the loop
public static void main(String[] args) {
Benchmark benchmark = new Benchmark();
benchmark.start();
}
public void start() {
//run the test 12000 times
for (int i = 0; i < 12000; i++) {
long start = System.nanoTime();
aqcuire_lock_multiple_times();
long end = System.nanoTime();
long time1 = end - start; // time to acquire lock multiple times
start = System.nanoTime();
acquire_lock_once();
end = System.nanoTime();
long time2 = end - start; // the time to acquire lock once
if (time1 <= time2) {
String m = MessageFormat.format(
"time1:{0}ns < time2:{1}ns, iteration:{2}", time1, time2, i);
System.out.println(m);
}else{
// acquire the lock once is faster as expected
}
}
}
public synchronized void aqcuire_lock_multiple_times() {
for (int i = 0; i < count; i++) {
synchronized (this) {
the_bool = !the_bool;
}
}
}
public synchronized void acquire_lock_once() {
for (int i = 0; i < count; i++) {
the_bool = !the_bool;
}
}
}
Here I compile it with jdk1.7 (the results with eclipse compiler are the same)
So my conclusion is that there is overhead.
Related
I'm trying to write game of life on many threads, 1 cell = 1 thread, it requires synchronization between threads, so no thread will start calculating it new state before other thread does not finish reading previous state. here is my code
public class Cell extends Processor{
private static int count = 0;
private static Semaphore waitForAll = new Semaphore(0);
private static Semaphore waiter = new Semaphore(0);
private IntField isDead;
public Cell(int n)
{
super(n);
count ++;
}
public void initialize()
{
this.algorithmName = Cell.class.getSimpleName();
isDead = new IntField(0);
this.addField(isDead, "state");
}
public synchronized void step()
{
int size = neighbours.size();
IntField[] states = new IntField[size];
int readElementValue = 0;
IntField readElement;
sendAll(new IntField(isDead.getDist()));
Cell.waitForAll.release();
//here wait untill all other threads finish reading
while (Cell.waitForAll.availablePermits() != Cell.count) {
}
//here release semaphore neader lower
Cell.waiter.release();
for (int i = 0; i < neighbours.size(); i++) {
readElement = (IntField) reciveMessage(neighbours.get(i));
states[i] = (IntField) reciveMessage(neighbours.get(i));
}
int alive = 0;
int dead = 0;
for(IntField ii: states)
{
if(ii.getDist() == 1)
alive++;
else
dead++;
}
if(isDead.getDist() == 0)
{
if(alive == 3)
isDead.setValue(1);
else
;
}
else
{
if(alive == 3 || alive == 2)
;
else
isDead.setValue(0);
}
try {
while(Cell.waiter.availablePermits() != Cell.count)
{
;
//if every thread finished reading we can acquire this semaphore
}
Cell.waitForAll.acquire();
while(Cell.waitForAll.availablePermits() != 0)
;
//here we make sure every thread ends step in same moment
Cell.waiter.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
processor
class extends thread and in run method if i turn switch on it calls step() method. well it works nice for small amount of cells but when i run abou 36 cells it start to be very slow, how can repair my synchronization so it woudl be faster?
Using large numbers of threads tends not to be very efficient, but 36 is not so many that I would expect that in itself to produce a difference that you would characterize as "very slow". I think more likely the problem is inherent in your strategy. In particular, I suspect this busy-wait is problematic:
Cell.waitForAll.release();
//here wait untill all other threads finish reading
while (Cell.waitForAll.availablePermits() != Cell.count) {
}
Busy-waiting is always a performance problem because you are tying up the CPU with testing the condition over and over again. This busy-wait is worse than most, because it involves testing the state of a synchronization object, and this not only has extra overhead, but also introduces extra interference among threads.
Instead of busy-waiting, you want to use one of the various methods for making threads suspend execution until a condition is satisfied. It looks like what you've actually done is created a poor-man's version of a CyclicBarrier, so you might consider instead using CyclicBarrier itself. Alternatively, since this is a learning exercise you might benefit from learning how to use Object.wait(), Object.notify(), and Object.notifyAll() -- Java's built-in condition variable implementation.
If you insist on using semaphores, then I think you could do it without the busy-wait. The key to using semaphores is that it is being able to acquire the semaphore (at all) that indicates that the thread can proceed, not the number of available permits. If you maintain a separate variable with which to track how many threads are waiting on a given semaphore at a given point, then each thread reaching that point can determine whether to release all the other threads (and proceed itself) or whether to block by attempting to acquire the semaphore.
Is the synchronized block on System.out.println(number); need the following code?
import java.util.concurrent.CountDownLatch;
public class Main {
private static final Object LOCK = new Object();
private static long number = 0L;
public static void main(String[] args) throws InterruptedException {
CountDownLatch doneSignal = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
Worker worker = new Worker(doneSignal);
worker.start();
}
doneSignal.await();
synchronized (LOCK) { // Is this synchronized block need?
System.out.println(number);
}
}
private static class Worker extends Thread {
private final CountDownLatch doneSignal;
private Worker(CountDownLatch doneSignal) {
this.doneSignal = doneSignal;
}
#Override
public void run() {
synchronized (LOCK) {
number += 1;
}
doneSignal.countDown();
}
}
}
I think it's need because there is a possibility to read the cached value.
But some person say that:
It's unnecessary.
Because when the main thread reads the variable number, all of worker thread has done the write operation in memory of variable number.
doneSignal.await() is a blocking call, so your main() will only proceed when all your Worker threads have called doneSignal.countDown(), making it reach 0, which is what makes the await() method return.
There is no point adding that synchronized block before the System.out.println(), all your threads are already done at that point.
Consider using an AtomicInteger for number instead of synchronizing against a lock to call += 1.
It is not necessary:
CountDownLatch doneSignal = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
Worker worker = new Worker(doneSignal);
worker.start();
}
doneSignal.await();
// here the only thread running is the main thread
Just before dying each thread countDown the countDownLatch
#Override
public void run() {
synchronized (LOCK) {
number += 1;
}
doneSignal.countDown();
}
Only when the 10 thread finish their job the doneSignal.await(); line will be surpass.
It is not necessary because you are waiting for "done" signal. That flush memory in a way that all values from the waited thread become visible to main thread.
However you can test that easily, make inside the run method a computation that takes several (millions) steps and don't get optimized by the compiler, if you see a value different than from the final value that you expect then your final value was not already visible to main thread. Of course here the critical part is to make sure the computation doesn't get optimized so a simple "increment" is likely to get optimized. This in general is usefull to test concurrency where you are not sure if you have correct memory barriers so it may turn usefull to you later.
synchronized is not needed around System.out.println(number);, but not because the PrintWriter.println() implementations are internally synchronized or because by the time doneSignal.await() unblocks all the worker threads have finished.
synchronized is not needed because there's a happens-before edge between everything before each call to doneSignal.countDown and the completion of doneSignal.await(). This guarantees that you'll successfully see the correct value of number.
Needed
No.
However, as there is no (documented) guarantee that there will not be any interleaving it is possible to find log entries interleaved.
System.out.println("ABC");
System.out.println("123");
could print:
AB1
23C
Worthwhile
Almost certainly not. Most JVMs will implement println with a lock open JDK does.
Edge case
As suggested by #DimitarDimitrov, there is one further possible use for that lock and it is to ensure a memory barrier is crossed befor accessing number. If that is the concern then you do not need to lock, all you need to do is make number volatile.
private static volatile long number = 0L;
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.)
I have two threads in my java programme, one is main thread and other thread is thread A which is spawned in main thread. now i want main thread to start thread A and wait till thread A has executed some part of its code in run method and thread A should suspend itself. main thread should then start running, run few lines of code and then again thread A should start from where it has stopped and vice versa. this should happen for n number of times.
I am trying as belows:
Thread A class:
public class ThreadA implements Runnable {
boolean suspended = false;
boolean stopped = false;
synchronized void stop() {
stopped = true;
suspended = false;
notify();
}
synchronized void suspend() {
suspended = true;
}
synchronized void resume() {
suspended = false;
notify();
}
void job() throws InterruptedException {
for (int i = 0; i < 5; i++)
synchronized (this) {
System.out.println("performing job.");
suspend();
while (suspended) {
notify();
suspended = false;
}
}
}
#Override
public void run() {
try {
job();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MainThread:
public class MainThread {
public static void main(String[] args) throws InterruptedException {
ThreadA a1=new ThreadA();
Thread t1=new Thread(a1);
synchronized (t1) {
t1.start();
for (int i = 0; i < 5; i++) {
t1.wait();
System.out.println("perform some action");
a1.resume();
}
}
}
}
Expected output:
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
Actual output:
performing job.
performing job.
performing job.
performing job.
performing job.
perform some action
I don't know why the whole for loop is getting executed in Thread A even when i've issued a notify() signal in job method.
You have two bugs here.
The first is that you are synchronizing and notifying different objects. Try this modified main, I changed synchronized (t1) to synchronized (a1) and t1.wait() to a1.wait().
public static void main(String[] args) throws InterruptedException {
ThreadA a1=new ThreadA();
Thread t1=new Thread(a1);
synchronized (a1) { // CHANGED FROM t1 to a1
t1.start();
for (int i = 0; i < 5; i++) {
a1.wait(); // CHANGED FROM t1 to a1
System.out.println("perform some action");
a1.resume();
}
}
}
The second bug is in the job() method, it calls notify() but not wait(). Here is a fixed version:
void job() throws InterruptedException {
for (int i = 0; i < 5; i++)
synchronized (this) {
System.out.println("performing job.");
suspend();
while (suspended) {
notify();
suspended = false;
wait(); // ADDED
}
}
}
The output from my test run is
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
Here is more simplified way
public class TwoThread {
public static void main(String[] args) throws InterruptedException {
ThreadA a1 = new ThreadA();
Thread t1 = new Thread(a1);
synchronized (a1) {
t1.start();
for (int i = 0; i < 5; i++) {
a1.wait();
System.out.println("perform some action " + i);
a1.notify();
}
}
}
}
public class ThreadA implements Runnable {
boolean suspended = false;
boolean stopped = false;
void job() throws InterruptedException {
for (int i = 0; i < 5; i++)
synchronized (this) {
System.out.println("performing job. " + i);
notify();
wait();
}
}
public void run() {
try {
job();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
To communicate between two threads only:
You do not need synchronized
You do not need locks
You do not need CAS (Compare And Swap). (Neither weak or strong)
You do not need setOpaque, setVolative nor setRelease
You just need VarHandle barrier (in Java).
Java VarHandle
The only requirement is ordered memory access
Here is a reasonably good article.
Synchronizing without Locks and Concurrent Data
Structures
In my daily work, I use variants of Dekker's and Peterson's algorithm
for asynchronous multi-threaded processing of web requests, sharing connection pools and collecting logs from cloud application with minor impact on performance
compared to the single thread un-contended performance.
Occasionally, I have to use setOpaque and getOpaque,
with VarHandle.loadLoadFence() and VarHandle.storeStoreFence()
to ensure ordered memory access and that is all you would need.
In my view the weak CAS is the furthers I would go,
as anything else I see as a violation of the multi-core CPU architecture.
However, unless you have an in-depth understanding of the actual
hardware that you are using and memory ordering constructs
used at the micro-instruction level, I suggest you use
standard Java concurrent locks, as they are the best
and optimal for general-purpose solutions.
To achieve, 10 x performance boost over the conventional CAS algorithms,
you need to make very stable layout of all shared objects in memory
and to strictly define which threads can read
and which can write to each variable and in which order.
You will need to consider the side effect on the CPU cache
of all memory loads and stores, and then to get these
to work in your advantage on the specific platform
that you are targeting. You will end up with
quite complex algorithms, but unbeatable performance.
You should explore the LMAX Disruptor library
as it has the open source library that implements many of these concepts
like ring-buffers and single thread can write to each variable.
LMAX Disruptor User Guide
Yet, I still see this as the the conservative approach to concurrency.
My current standard is to have algorithm that tolerate racing
and discard data and repeat processing if they detect racing condition.
I use the state embeded counters, indexes, flags and hashes,
to detect thread collision and chose thread that will give up
and use another memory structure for its operation.
However, due to thread focused memory structures and
optimized reference sharing these occur rarely (like one in 1 million)
Yet, if you have good understanding of CPU cache operations
and any specialized platform instruction you can get CPU
cache to work in your advantage and execute reads and writes,
and sharing of cache lines between cores, as a side effect
of your instructions without you having to explicitly issue
commands to do this.
BTW, the NodeJS (V8) engine was an attempt to minimize contention and locking by having a single thread event loop to distribute events to all other I/O and utility library threads, so they do not have to compete between themselves for access to events and shared memory.
As you can see, NodeJS had great success,
and if we are talking about the special purpose algorithms
you can take it even further.
NodeJS architecture
Happy reading.
There is little reason to synchronize multiple threads if one threads waits while another does its thing. One could use Executors to get the same result with less work and still got the feeling that one is playing with the threads.
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
for(int i = 0; i<5;i++) {
executor.submit(new PrintTask("performing job."));
executor.submit(new PrintTask("perform some action"));
}
executor.shutdown();
}
private static class PrintTask implements Runnable {
private String string;
public PrintTask(String string) {
this.string = string;
}
#Override
public void run() {
System.out.println(string);
}
}
}
The question is as follows, since the barrier is only called using down() so that it would wait for the n threads to arrive and then execute all n threads together in the critical region now how do I inform the threads calling on barrier.down that it can move on now. I tried adding notifyAll() after phase2() and that doesn't work. Help? :)
public class cyclicBarrier {
private int n;
private int count;
private semaphore mutex;
private semaphore turnstile;
private semaphore turnstile2;
public cyclicBarrier(int n){
this.n = n;
this.count = 0;
this.mutex = new semaphore(1);
this.turnstile = new semaphore(0);
this.turnstile2 = new semaphore(0);
}
public synchronized void down() throws InterruptedException{
this.phase1(); //waits for n threads to arrive
this.phase2(); //waits for n threads to execute
}
private synchronized void phase1() throws InterruptedException {
this.mutex.down();
this.count++;
if(this.count == this.n){
for(int i = 0; i < this.n; i++){
this.turnstile.signal(); //when n threads received then move on to phase 2
}
}
this.mutex.signal();
this.turnstile.down(); //keeps waiting till I get n threads
}
private synchronized void phase2() throws InterruptedException {
this.mutex.down();
this.count--;
if(this.count == 0){
for(int i = 0; i < this.n; i++){
this.turnstile2.signal(); //reset the barrier for reuse
}
}
this.mutex.signal();
this.turnstile2.down(); //keeps waiting till n threads get executed
}
}
public class semaphore {
private int counter;
public semaphore(int number){
if (number > 0) {
this.counter = number;
}
}
public synchronized void signal(){
this.counter++;
notifyAll();
}
public synchronized void down() throws InterruptedException{
while (this.counter <= 0){
wait();
}
this.counter--;
}
}
I see you're using the solution from The Little Book of Semaphores. One main point of the book is that you can solve many coordination problems using semaphores as the only coordination primitive. It is perfectly fine to use synchronized to implement a semaphore, since that is necessary to do it correctly. It misses the point, however, to use synchronized in the methods which solve a puzzle that is supposed to be solved with semaphores.
Also, I think it doesn't work in your case: don't you get a deadlock at this.turnstile.down()? You block on a semaphore which holding an exclusive lock (through synchronized) on the object and method which would allow that semaphore to get released.
Addressing the question as stated: you signal to threads that they can proceed by returning from barrier.down(). You ensure that you don't return too soon by doing turnstile.down().
Aside: Semaphore implementation
Your semaphore implementation looks correct, except that you only allow non-negative initial values, which is at least non-standard. Is there some motivation for doing this that I can't see? If you think negative initial values are wrong, why not throw an error instead of silently doing something else?
Aside: Other synchronization primitives
Note that the java constructs synchronized, .wait() and .notify() correspond to the Monitor coordination primitive. It may be instructive to solve the puzzles with monitors (or other coordination primitives) instead of semaphores, but I would recommend keeping those efforts separate. I've had a bit of fun trying to solve a puzzle using Haskell's Software Transactional Memory.
Aside: On runnability
You say you have tried things, which indicates that you have some code that allows you to run the code in the question. It would have been helpful if you had included that code, so we could easily run it too. I probably would have checked that my hypothesized deadlock actually occurs.