2
public class MyResource {

private int count = 0;

void increment() {

    count++;

}

void insert() {    // incrementing shared resource count
    for (int i = 0; i < 100000000; i++) {
        increment();
    }

}

void insert1() {       //incrementing shared resource count
    for (int i = 0; i < 100000000; i++) {
        increment();
    }

}

void startThread() {

    Thread t1 = new Thread(new Runnable() {  //thread incrementing count using insert()

        @Override
        public void run() {
            insert();
        }
    });

    Thread t2 = new Thread(new Runnable() {    //thread incrementing count using insert1()

        @Override
        public void run() {
            insert1();
        }
    });

    t1.start();
    t2.start();

    try {
        t1.join(); //t1 and t2 race to increment count by telling current thread to wait
        t2.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

void entry() {
    long start = System.currentTimeMillis();
    startThread();            //commenting insert(); insert1() gives output as time taken = 452(approx)   110318544  (obvious)

    // insert(); insert1();     //commenting startThread() gives output as time taken = 452(approx)   200000000

    long end = System.currentTimeMillis();
    long time = end - start;
    System.out.println("time taken = " + time);

    System.out.println(count);
}

}

Program entry point is from entry() method.

1.Only using insert(); insert1(); (Normal method calling ) and commenting startThread()(which executes thread) gives me result as shown in code.

2.Now commenting insert(); insert1(); and using startThread()(which executes thread) gives me result as shown in code.

3.Now I synchronize increment() gives me output as time taken = 35738 200000000

As Above synchronizing avoids access of shared resource but on other hand it takes lot of time to process.

So what's use of this synchronizing if it decrease the performance ?

Javed Solkar
  • 162
  • 11

3 Answers3

0

You are not suppose to use synchronization to increase performance, you are suppose to use it in order to protect shared resources. Is this a real code example? Because if you want to use threads here in order to split the work synchronize

increment() 

is not the best approach...

EDIT

as described here, you can change the design of this specific code to divide the work between the 2 threads more efficiently. i altered their example to fit your needs, but all the methods described there are good.

import java.util.*;
import java.util.concurrent.*;
import static java.util.Arrays.asList;

public class Sums {

    static class Counter implements Callable<Long> {

        private final long _limit;
        Counter(long limit) {
            _limit = limit;
        }

        @Override
        public Long call() {
            long counter = 0;
            for (long i = 0; i <= _limit; i++) {
                counter++
            }
            return counter;
        }                
    }

    public static void main(String[] args) throws Exception {

        int counter = 0;
        ExecutorService executor = Executors.newFixedThreadPool(2);
        List <Future<Long>> results = executor.invokeAll(asList(
            new Counter(500000), new Counter(500000));
        ));
        executor.shutdown();

        for (Future<Long> result : results) {
            counter += result.get();
        }                
    }    
}

and if you must use synchronisation, AtomicLong will do a better job.

Lital Kolog
  • 1,301
  • 14
  • 39
  • I got this code from Cave of Programming and slightly twisted by me to learn synchronization.............I first tried to increase performance by using threads but results were unexpected because of non atomicity so I tried to synchronize that method which results into very low performance.......................What's the best approach ? – Javed Solkar May 10 '15 at 17:34
  • @ Javed Solkar, Edited my answer. – Lital Kolog May 10 '15 at 17:57
  • And another thing, sometimes you don't have a choice but to use synchronization. In the example you posted it may not be the best approach but in real systems, like an application server which serves hundreds of clients multithreaded and synchronization is a must. – Lital Kolog May 10 '15 at 18:06
0

Performance is not the only factor. Correctness can also be very important. Here is another question that has some low level details about the keyword synchronized.

If you are looking for performance, consider using the java.util.concurrent.atomic.AtomicLong class. It has been optimized for fast, atomic access.

EDIT:

Synchonized is overkill in this use case. Synchronized would be much more useful for FileIO or NetworkIO where the calls are much longer and correctness is much more important. Here is the source code for AtomicLong. Volatile was chosen because it is much more performant for short calls that change shared memory.

Adding a synchronized keyword adds in extra java bytecode that does a lot of checking for the right state to get the lock safely. Volatile will put the data in main memory, which takes longer to access, but the CPU enforces atomic access instead of the jvm generating extra code under the hood.

Community
  • 1
  • 1
yxre
  • 3,576
  • 21
  • 20
0

Sometimes you just want two or more things to go on at the same time. Imagine the server of a chat application or a program that updates the GUI while a long task is running to let the user know that processing is going on

Raffaele
  • 20,627
  • 6
  • 47
  • 86
  • Two or more things to go on at the same time, I'll use threads to do that. But if there is any shared resources than I have to use synchronization which will make application slower.................... than why to use synchronized ?. – Javed Solkar May 10 '15 at 18:02
  • Because sometimes you don't have other options, so exchange performance for application requirements – Raffaele May 10 '15 at 18:14