Multi threading - java

I have an idea about multi-threading but I never worked on it. So, when I see my application at work... I haven't seen any class extending Thread creating a Thread. So, synchronized keyword is used when 2 objects try to access a variable at the same time.. we use synchronized to avoid conflicts.
Example:
public class Test {
private static int count = 0;
public static synchronized void incrementCount() {
count++;
}
}
If test class was using by an object then it makes sense to add synchronized to incrementcount(). But when you don't extend Thread or Runnable then what's the use of writing synchronized.

Synchronized isn't for threads or Runnables, it's used for data structures that are accessed by multiple threads in order to make sure each thread accesses them in a way that doesn't corrupt their data. Your own example is a rudimentary case of this, where count is incremented in a way that isn't threadsafe (using ++, see this question), so it needs locking to make sure only one thread at a time can increment it.
If there's other code that accesses count it also needs to be synchronized so that updates to count are visible to it. If all you're doing is incrementing a counter then it makes more sense to use a class like java.util.concurrent.atomic.AtomicInteger, and you can do without the synchronized keyword altogether.
For using synchronized to make sense it does assume there are multiple threads. Even if your own code doesn't create new threads, there can be cases where multiple threads are calling your code (such as in a servlet container, where the container manages a threadpool and allocates a thread to each incoming request).

A class does not need to extend Thread or implements Runnable to mark it's method as synchronized to protect from multiple thread access
Your class may a parameter to some other thread class and that thread class may have multiple instances. To provide strong consistency of data, you have protect your critical section of code & data.
Just change your code example as below.
I am demonstrating "synchronized" at object level rather than class level ( static synchronized)
class Test {
private int count = 0;
public void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
Test t = new Test();
for ( int i=0; i<10; i++){
new Thread(new MyRunnable(t)).start();
}
}
}
Your class Test has been passed as a parameter to thread MyRunnable. Now you have created multiple instances of threads. In absence of synchronized keyword, the output is unpredictable as follows.
java SynchronizedDemo
Count:2
Count:3
Count:2
Count:7
Count:6
Count:5
Count:4
Count:10
Count:9
Count:8
If I change
public void incrementCount() {
to
public synchronized void incrementCount() {
the output is:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10
On a different note, you have make your method as static synchronized. That means lock is maintained at class level instead of object level.
Have a look at oracle documentation page for better understanding.
Demo of code for absence of "static synchronized"
class Test {
private static int count = 0;
public static void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
for ( int i=0; i<10; i++){
Test t = new Test();
new Thread(new MyRunnable(t)).start();
}
}
}
output:
Count:5
Count:4
Count:3
Count:2
Count:10
Count:9
Count:8
Count:7
Count:6
After making
public static void incrementCount() {
to
ppublic static synchronized void incrementCount() {
output:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10
In this example, unlike earlier, we have created 10 different Test instances.

i++, even though it looks like a single instruction, is actually multiple instructions:
Set a temporary variable to 1+i.
Set the variable i to the temporary variable.
However, suppose the thread that executes i++ is interrupted after step 1, and the interrupting thread also calls i++. Then, this would happen:
(Suppose i=1)
Original thread: set temporary variable1 to 1+i, or 2.
Interrupting thread: set temporary variable2 to i+1, also 2
Interrupting thread: set i to temporary variable2. Now i=2
Original thread: set i to temporary variable1. Now i=2
The problem is that if i++ is called twice, it should be 3, not 2.
A synchronized void would put a lock on the variable i until the entire void completes executing. For example:
Original thread: set temporary variable1 to 1+i, or 2. Puts a lock on the variable i.
Interrupting thread: TRIES TO set temporary variable2 to i+1, but waits because of the lock on variable i
Original thread: set i to temporary variable1. Now i=2. The variable i is now unlocked.
Interrupting thread: "notices" that i has been unlocked, so it sets temporary variable2 to i+1 which is 3.
Interrupting thread: sets i to 3, which is expected behavior.
synchronized voids essentially lock variables temporarily to avoid confusing the program's execution.

Related

Using java semaphores as locks between two Runnable classes

I have three objects which are instances of two different classes implementing Runnable interface. One of the objects changes counters of the other two objects, but I want to make sure the whole update operation is not interrupted by the other threads (i.e. I want to use a lock for my critical section).
In the code below (this is an illustration of the actual code, not itself), I want to make sure the code in the critical section is executed without any interruptions.
One thought I have is defining a binary Semaphore, m, in the Worker class and surround every operation that touches value and operations with m.acquire() followed by m.release(). But, in the 'Runner' class, I have a call to incrementValue() and if I surround CS with acquire()/release() calls while I have the same thing within incrementValue(), it does not make sense.
I am a bit confused about where I should be putting my semaphores to achieve mutual exclusion.
Thanks
class Worker implements Runnable{
int value;
int operations;
// Semaphore m = new Semaphore(1);
...
...
void incrementValue(int n){
// m.acquire() here??
this.operations++;
this.value += n;
// m.release() here??
}
...
#Override
public void run(){
...
this.operations++;
this.value = getRandomNum();
...
}
}
class Runner implements Runnable {
Worker a, b;
...
...
#Override
public void run(){
...
// Start of the CS
// a.m.acquire() here?
// b.m.acquire() here?
a.incrementValue(x);
System.out.println("Value in WorkerA incremented by " + x);
b.incrementValue(y);
System.out.println("Value in WorkerB incremented by " + y);
// a.m.release() here?
// b.m.release() here?
// end of the CS
...
}
...
}
Sounds like the problem you are facing is the same problem that ReentrantLock is meant to solve. ReentrantLock lets you do this:
final ReentrantLock m = new ReentrantLock();
void foo() {
m.lock();
doFooStuff();
m.unlock();
}
void bar() {
m.lock();
foo();
doAdditionalBarStuff();
m.unlock();
}
The lock() call checks to see whether or not the calling thread already owns the lock. If the caller does not, then it first acquires the lock, waiting if necessary, and finally, before it returns it sets a count variable to 1.
Subsequent lock() calls from the same thread will see that the thread already owns the lock, and they will simply increment the counter and return.
The unlock() calls decrement the counter, and only release the lock when the count reaches zero.

Java: Multithreading inconsistency [duplicate]

I have a thread class which implements runnable and an int counter as instance variable. Two synchronized methods add and sub. When I run my test class somehow it is printing wrong results once in couple of times. As far as I understand when a method is synchronized, entire object will be locked for accessing by other threads, with this logic every time we should get same results right? Some how that is not the case. Am I missing something?
My machine is Windows 7, 64 bit.
public class ThreadClass implements Runnable {
int counter = 0;
#Override
public void run() {
add();
sub();
}
public synchronized void add() {
System.out.println("ADD counter" + (counter = counter + 1));
}
public synchronized void sub() {
System.out.println("SUB counter" + (counter = counter - 1));
}
}
Testclass
public class ThreadTest {
public static void main(String args[]) {
ThreadClass tc = new ThreadClass();
Thread tc0 = new Thread(tc);
tc0.start();
tc0.setPriority(Thread.MAX_PRIORITY);
Thread tc1 = new Thread(tc);
tc1.start();
tc1.setPriority(Thread.NORM_PRIORITY);
Thread tc2 = new Thread(tc);
tc2.start();
tc2.setPriority(Thread.MIN_PRIORITY);
}
}
Results
ADD counter1
ADD counter2
SUB counter1
SUB counter0
ADD counter1
SUB counter0
Note: You may need to do couple of runs to produce this inconsistency.
Your results look correct.
During the execution of the methods, an exclusive lock on the object is obtained, but between the add() and sub() calls, the threads can freely interleave.
If you end up with a total of 0 after all the threads have run, then none of them overwrote eathother and the access to counter was synchronized.
If you wish to have counter only go from 0 to 1 sequentially and never hit 2, then do the following (which will render the method-level synchronization redundant so long as no other classes are involved):
#Override
public void run() {
synchronize(this) {
add();
sub();
}
}
However, this makes the whole point of the threads useless since you could do that in a single-threaded loop.
Synchronization will indeed mean that all threads will block waiting to acquire a lock before they can enter the synchronized block. Only one thread can ever have the lock on the object, so only one thread can be in the add() or sub() methods.
However, this does not imply anything else about the ordering of threads. You're starting three threads - the only guarantee is that they won't stomp on each other by running the add or sub methods at once. Thread 1 can call add(), then thread 3 can call add(), then thread 2 can call add(), then they can all call sub(). Or they could all call add() and then sub() each. Or any mixture - the only requirement being that each thread calls add() before it calls sub() and that no two threads will ever call add() or sub() while another thread is in that method.
Aside: it can be, in some cases, bad form to synchronize on this, as it's public - it's often preferred to use an internal private Object to lock on so that no other callers can take your lock and violate any locking strategies you have designed.
There is nothing wrong with either set of results. They are both perfectly consistent with what your code does. The running order of multiple threads is not guaranteed.
Your 'synchronized' methods ensure you get valid results -- each call to add in fact adds one and each call to sub in fact subtracts one. Without them, you could get a final result other than zero.

Confusion Regarding java threads on same/different objects

public class Computation extends Thread {
private int num;
private boolean isComplete;
public Computation(int nu) {
num = nu;
}
public void run() {
System.out.println("Thread Called is: " + Thread.currentThread().getName());
}
public static void main(String... args) {
Computation [] c = new Computation[4];
for (int i = 0; i < 3; i++) {
c[i] = new Computation(i);
c[i].start();
}
}
}
My Question is in main function we are creating every time a new Computation object on which the thread is being started then why we need to snchrnoized the run method? As we know for every different class object 'this' reference is different so we don't need to synchronize.
Also in another Example:
public class DiffObjSynchronized implements Runnable {
#Override
public void run() {
move(Thread.currentThread().getId());
}
public synchronized void move(long id) {
System.out.print(id + " ");
System.out.print(id + " ");
}
public static void main(String []args) {
DiffObjSynchronized a = new DiffObjSynchronized();
/**** output ****/
// 8 9 8 9
new Thread(a).start();
new Thread(new DiffObjSynchronized()).start();
}
}
Here is second example just like first we create a Thread on 2 different instances of class. Here we synchronize the move() method but by definition:
"two different objects can enter the synchronized method at the same time"
Please share your feedback?
If I understand you correctly, your question is: "Why is the move method synchronized?"
The answer is: it shouldn't be, for two reasons:
It doesn't access any fields, so there is nothing that could be corrupted by having many threads inside that method at once.
Each thread gets a different instance of the object, and thus a different lock. So the synchronized modifier makes no difference. Each thread can still enter its own instance's move method because they have separate locks.
You only need to synchronize when you have some data which is being shared between threads, and at least one thread is modifying that data.
Your threads are operating on different objects since you create a new instance for each thread. The intrinsic lock used by synchronized belongs to the instance. So the synchronized methods entered by your threads are guarded by different locks.
You need to understand how synchronization works.
Threads take a 'lock' on the object on which you are synchronizing when they enter the synchronized block. If you have a synchronized method then in that case the object becomes the 'this' instance. Now, no 2 threads can take a lock on the same object at the same time. object locks are mutex based in philosophy so only once thread can hold the mutex at a time. When the thread holding the lock exits the synchronized method or the block, it releases the mutex and thus the object lock becomes available to other threads to request lock on.
This link explains the concepts excellently. It has pictures about disassembled byte code which shows how threads take and leave locks and why 2 threads on 2 different object dont block each other.

Why modifying a shared variable in one threads affects the other thread even without using volatile?

Here I have three simple classes:
Class 1:
public class ThreadSyncMain {
public static int count = 0; // volatile is not use
public static void main(String[] args) {
Thread thread1 = new Thread( new Thread1(),"Thread1" );
Thread thread2 = new Thread( new Thread2(),"Thread2");
thread1.start();
thread2.start();
}
}
Class 2:
public class Thread1 implements Runnable{
public void run() {
System.out.println("Thread1 Count :: "+ThreadSyncMain.count);
ThreadSyncMain.count++;
}
}
Class 3:
public class Thread2 implements Runnable{
public void run() {
System.out.println("Thread2 Count :: "+ThreadSyncMain.count);
}
}
The output is:
Thread1 Count :: 0
Thread2 Count :: 1
This means thread1 changed the value of count. So why change in thread1 affects in thread2 as I am not using any "volatile" keyword. Is "volatile" keyword not a matter in this scenario? How can I modify the code so as to test "volatile"?
Thanks in advance.
Update part:
I am updating the code after doing some hit and trial testing. Class 1 remains same. Here is the updated code:
Class 2: I added 100 millisecond delay.
public class Thread1 implements Runnable{
public void run() {
System.out.println("Thread1 Count :: "+ThreadSyncMain.count);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadSyncMain.count++;
}
}
Class 3: Added while loop. Inside it count is continuously monitored.
public class Thread2 implements Runnable{
public void run() {
while(true)
{
if(ThreadSyncMain.count == 1)
{
System.out.println("Thread2 Count :: "+ThreadSyncMain.count);
}
}
}
}
Now in this situation I have got the following outputs:
1. If "volatile" is not used in class1 output is:
Thread1 Count :: 0
2. If "volatile" is used in class1 output is:
Thread1 Count :: 0
Thread2 Count :: 1
Thread2 Count :: 1
Thread2 Count :: 1
.
.
.
Why volatile comes into picture in this scenario?
There's a memory view associated with each thread. These views are not guaranteed to be consistent between threads without the usage of locks. As such, sharing a variable as you've done above (without volatile) will work, since it's visible across threads, but can give you unreliable results. Using the volatile keyword means that the variable is consistently read between threads.
See here, and in particular note:
Volatile fields are special fields which are used for communicating
state between threads. Each read of a volatile will see the last write
to that volatile by any thread; in effect, they are designated by the
programmer as fields for which it is never acceptable to see a "stale"
value as a result of caching or reordering.
Volatile will guarantee the side effects from thread 1 become visible to thread 2. Without volatile, changes might, or might not, be visible.
Testing the effect of volatile is difficult, since it depends on low level aspects like hardware architecture, threading implementation, compiler optimization, and exact timing of even by the scheduler.
If I were to do so, I would write multithreaded tests that generate a high concurrency, and make sure I run on a multi-processor implementation. Then I might observe differences between code with and without volatile. The outcome of the tests would still be undeterministic.
It is possible the compiler isn't caching counter because it is a class wide variable. So the writes are in memory.
If you want to test volatile and non volatile write/reads..
public class VolatileExperiment
{
private int counter ;
private volatile int volatile_counter;
public void Counter()
{
new Thread( new Runnable(){
public void run()
{
++counter;
++volatile_counter;
//print
}
}).start();
new Thread( new Runnable(){
public void run()
{
++counter;
++volatile_counter;
//print
}
}).start();
//print counter
//print volatile
}
}
Using volatile ensures that compiler doesn't optimize code, so writes are done in memory and not in thread memory. So you should see volatile_counter updated.. while counter may not be affected

Inconsistent results with java threads

I have a thread class which implements runnable and an int counter as instance variable. Two synchronized methods add and sub. When I run my test class somehow it is printing wrong results once in couple of times. As far as I understand when a method is synchronized, entire object will be locked for accessing by other threads, with this logic every time we should get same results right? Some how that is not the case. Am I missing something?
My machine is Windows 7, 64 bit.
public class ThreadClass implements Runnable {
int counter = 0;
#Override
public void run() {
add();
sub();
}
public synchronized void add() {
System.out.println("ADD counter" + (counter = counter + 1));
}
public synchronized void sub() {
System.out.println("SUB counter" + (counter = counter - 1));
}
}
Testclass
public class ThreadTest {
public static void main(String args[]) {
ThreadClass tc = new ThreadClass();
Thread tc0 = new Thread(tc);
tc0.start();
tc0.setPriority(Thread.MAX_PRIORITY);
Thread tc1 = new Thread(tc);
tc1.start();
tc1.setPriority(Thread.NORM_PRIORITY);
Thread tc2 = new Thread(tc);
tc2.start();
tc2.setPriority(Thread.MIN_PRIORITY);
}
}
Results
ADD counter1
ADD counter2
SUB counter1
SUB counter0
ADD counter1
SUB counter0
Note: You may need to do couple of runs to produce this inconsistency.
Your results look correct.
During the execution of the methods, an exclusive lock on the object is obtained, but between the add() and sub() calls, the threads can freely interleave.
If you end up with a total of 0 after all the threads have run, then none of them overwrote eathother and the access to counter was synchronized.
If you wish to have counter only go from 0 to 1 sequentially and never hit 2, then do the following (which will render the method-level synchronization redundant so long as no other classes are involved):
#Override
public void run() {
synchronize(this) {
add();
sub();
}
}
However, this makes the whole point of the threads useless since you could do that in a single-threaded loop.
Synchronization will indeed mean that all threads will block waiting to acquire a lock before they can enter the synchronized block. Only one thread can ever have the lock on the object, so only one thread can be in the add() or sub() methods.
However, this does not imply anything else about the ordering of threads. You're starting three threads - the only guarantee is that they won't stomp on each other by running the add or sub methods at once. Thread 1 can call add(), then thread 3 can call add(), then thread 2 can call add(), then they can all call sub(). Or they could all call add() and then sub() each. Or any mixture - the only requirement being that each thread calls add() before it calls sub() and that no two threads will ever call add() or sub() while another thread is in that method.
Aside: it can be, in some cases, bad form to synchronize on this, as it's public - it's often preferred to use an internal private Object to lock on so that no other callers can take your lock and violate any locking strategies you have designed.
There is nothing wrong with either set of results. They are both perfectly consistent with what your code does. The running order of multiple threads is not guaranteed.
Your 'synchronized' methods ensure you get valid results -- each call to add in fact adds one and each call to sub in fact subtracts one. Without them, you could get a final result other than zero.

Categories