Java: Multithreading inconsistency [duplicate] - java

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.

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.

Multi threading

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.

What happens when few threads trying to call the same synchronized method?

so I got this horses race and when a horse getting to the finishing line, I invoke an arrival method. Let's say I got 10 threads, one for each horse, and the first horse who arrives indeed invoking 'arrive':
public class FinishingLine {
List arrivals;
public FinishingLine() {
arrivals = new ArrayList<Horse>();
}
public synchronized void arrive(Horse hourse) {
arrivals.add(hourse);
}
}
Ofc I set the arrive method to synchronized but I dont completely understand what could happen if it wasnt synchronized, the professor just said it wouldn't be safe.
Another thing that I would like to understand better is how it is decided which thread will after the first one has been finished? After the first thread finished 'arrive' and the method get unlocked, which thread will run next?
1) It is undefined what the behaviour would be, but you should assume that it is not what you would want it to do in any way that you can rely upon.
If two threads try to add at the same time, you might get both elements added (in either order), only one element added, or maybe even neither.
The pertinent quote from the Javadoc is:
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.)
2) This is down to how the OS schedules the threads. There is no guarantee of "fairness" (execution in arrival order) for regular synchronized blocks, although there are certain classes (Semaphore is one) which give you the choice of a fair execution order.
e.g. you can implement a fair execution order by using a Semaphore:
public class FinishingLine {
List arrivals;
final Semaphore semaphore = new Semaphore(1, true);
public FinishingLine() {
arrivals = new ArrayList<Horse>();
}
public void arrive(Horse hourse) {
semaphore.acquire();
try {
arrivals.add(hourse);
} finally {
semaphore.release();
}
}
}
However, it would be easier to do this with a fair blocking queue, which handles the concurrent access for you:
public class FinishingLine {
final BlockingQueue queue = new ArrayBlockingQueue(NUM_HORSES, true);
public void arrive(Horse hourse) {
queue.add(hourse);
}
}

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.

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