Using System.out.println(Thread.currentThread().getName() + " " +count); leads to synchronization - java

I was learning multithreading in java, In the tutorial, it said removing synchronized should make the program buggy and it did, So I was just experimenting around and wrote a print line System.out.println(Thread.currentThread().getName() + " " +count);
and removed the synchronized word, and even then the program worked fine. But if only synchronized word is removed and the printline(System.out.println(Thread.currentThread().getName() + " " +count);) is not added the program is buggy ad expected.
I can't understand how adding a print line can make it synchronized.
public class intro implements Runnable {
int n=10000;
private int count = 0;
public int getCount() { return count; }
public synchronized void incrSync() { count++; }
public void run () {
for (int i=0; i<n; i++) {
incrSync();
//System.out.println(Thread.currentThread().getName() + " " +count);
}
}
public static void main(String [] args) {
intro mtc = new intro();
Thread t1 = new Thread(mtc);
Thread t2 = new Thread(mtc);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException ie) {
System.out.println(ie);
ie.printStackTrace();
}
System.out.println("count = "+ mtc.getCount());
}
}

Synchronization issues happen between threads when multiple threads attempt access to the same field at the same time.
Without the printing the run method sits in a tight loop accessing the counter almost continuously. Making multiple threads do that without synchronization is very likely to cause a fault.
By adding the printing you are changing the loop to spend most (almost all) of its time printing and only occasionally increment the count. This is much less likely to cause contention.
The code is still buggy with the printing, the only difference is that the contention will happen much less often and your test of just 1000 loops is not sufficient to demonstrate the issue. You'd probably have to run it for a few years before the threads clashed.
This is a classic demonstration of why threading issues are so difficult to find and fix. That loop (with it's print statement) could run on multiple threads for years without contention but if just one clash between threads happens then the code breaks. Imagine that happening in a heart pacemaker or a satellite or a nuclear power station!

The println method calls newline, which is a method with a synchronized-block. It is giving correct result, though it is not thread safe.
Consider T1 read count 5 and T2 read count 5 simultaneously, then race condition happen. It is giving correct result because you are using System.out.println(Thread.currentThread().getName() + " " +count); which is blocking. Increase thread number.
private void newLine() {
try {
synchronized (this) {
ensureOpen();
textOut.newLine();
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush)
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}

Related

Java code - Threads blocking each other

I am new to multithreading. I am trying to write a program where I have two threads. One thread prints odd number and then gives up the monitor lock using wait() and similarly other thread prints the even number and gives up the lock after printing the number
I have got 4 classes
Odd.java (print odd numbers between 1-100)
Even.java(print even number between 1-100)
SomeMaths.java( has got logic for printing odd and even numbers )
OEApp.java (Main class that starts the threads)
Problem - My code works as expected most of the times i.e it print number 1 to 100 in order. Both the thread take turns. But I noticed that there is a bug.Sometimes the even thread gets scheduled first and gets below output
2 **********
1 ###############################
After that nothing gets printed, Looks like there is a deadlock situation. I am not able to figure out why. Please help me to understand this
public class SomeMaths {
public synchronized void printOdd(){
for( int i=1;i<=100;i++){
if(i%2 !=0) {
System.out.println(i + " ###############################");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
public synchronized void printEven(){
for(int i=1;i<=100;i++){
if(i%2 ==0){
System.out.println(i +" **********");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notify();
}
}
}
public class Odd implements Runnable {
SomeMaths sm;
public Odd(SomeMaths sm){
this.sm = sm;
}
#Override
public void run(){
sm.printOdd();
}
}
public class Even extends Thread {
SomeMaths sm;
public Even(SomeMaths sm){
this.sm = sm;
}
#Override
public void run(){
sm.printEven();
}
}
public class OEApp {
public static void main(String[] args) {
SomeMaths sm = new SomeMaths();
Thread odd = new Thread(new Odd(sm));
Thread even = new Thread(new Even(sm));
odd.start();
even.start();
try {
odd.join();
even.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I believe it works this way:
Even thread starts, 1 is odd so it calls notify (notifying no one), then 2 is even so it prints a message and waits
Odd thread starts, 1 is odd so it prints a message and waits
There's no one to call notify so both threads wait forever
What is your purpose for using the synchronize keyword ?
It can only assure you that your function will not be running multiple times at the same time.
I assume that you want one thread to notify another ? Is that right ?
But what if the notify is called before the wait occurred ?
You know that you can use the debugger to see each thread, and thus know where each thread is stuck ?
Please keep in mind, once start is called, you can't know which thread will have cpu time.
Furthermore you are trying to synchronize two threads (by the use of the notify/wait mecanism), but there are other mecanisms that will be proved simpler (e.g. semaphore: each thread having it own semaphore, acquiring it own semaphore and releasing the other one semaphore; initialize each semaphore to 1 and it will go smoothly).
P.S. :
I am forced to post an answer, but it should be a comment; sorry
Why use both runnable and thread interface ? Furthermore your Even class is already a thread, so no use to wrap it once again.
See https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem

Delay in running thread due to system.out.println statement [duplicate]

This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
In the following code, if i use sysout statement inside for loop then the code executes and goes inside the loop after the condition met but if i do not use sysout statement inside loop then then infinite loop goes on without entering inside the if condition even if the if condition is satisfied.. can anyone please help me to find out the exact reason for this. Just A sysout statement make the if condition to become true. why is it so?
The code is as follows:-
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo( String name){
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
for(;;)
{
//Output 1: without this sysout statement.
//Output 2: After uncommenting this sysout statement
//System.out.println(Thread.currentThread().isInterrupted());
if(TestThread.i>3)
{
try {
for(int j = 4; j > 0; j--) {
System.out.println("Thread: " + threadName + ", " + j);
}
} catch (Exception e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
}
}
public void start ()
{
System.out.println("Starting " + threadName );
if (t == null)
{
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
static int i=0;
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
i+=4;
System.out.println(i);
}
}
Output without sysout statement in the infinite loop:-
Output with sysout statement in the infinite loop:-
The problem here can be fixed by changing
static int i=0;
to
static volatile int i=0;
Making a variable volatile has a number of complex consequences and I am not an expert at this. So, I'll try to explain how I think about it.
The variable i lives in your main memory, your RAM. But RAM is slow, so your processor copies it to the faster (and smaller) memory: the cache. Multiple caches in fact, but thats irrelevant.
But when two threads on two different processors put their values in different caches, what happens when the value changes? Well, if thread 1 changes the value in cache 1, thread 2 still uses the old value from cache 2. Unless we tell both threads that this variable i might be changing at any time as if it were magic. That's what the volatile keyword does.
So why does it work with the print statement? Well, the print statement invokes a lot of code behind the scenes. Some of this code most likely contains a synchronized block or another volatile variable, which (by accident) also refreshes the value of i in both caches. (Thanks to Marco13 for pointing this out).
Next time you try to access i, you get the updated value!
PS: I'm saying RAM here, but its probably the closest shared memory between the two threads, which could be a cache if they are hyperthreaded for instance.
This is a great explanation too (with pictures!):
http://tutorials.jenkov.com/java-concurrency/volatile.html
When you are accessing a variable value, the changes aren't written to (or loaded from) the actual memory location every time. The value can be loaded into a CPU register, or cached, and sit there until the caches are flushed. Moreover, because TestThread.i is not modified inside the loop at all, the optimizer might decide to just replace it with a check before the loop, and get rid of the if statement entirely (I do not think it is actually happening in your case, but the point is that it might).
The instruction that makes the thread to flush its caches and synchronize them with the current contents of physical memory is called memory barrier. There are two ways in Java to force a memory barrier: enter or exit a synchronized block or access a volatile variable.
When either of those events happens, the cached are flushed, and the thread is guaranteed to both see an up-to-date view of the memory contents, and have all the changes it has made locally committed to memory.
So, as suggested in comments, if your declare TestThread.i as volatile, the problem will go away, because whenever the value is modified, the change will be committed immediately, and the optimizer will know not to optimizer,e the check away from the loop, and not to cache the value.
Now, why does adding a print statement changes the behaviour? Well, there is a lot of synchronization going on inside the io, the thread hits a memory barrier somewhere, and loads the fresh value. This is just a coincidence.

Second thread does not run() in for loop

This is a test code I have created to study threads. It consist of two threads assigned to the same Runnable. They have to deduct 5 to an int, and stop if the int is not big enough to deduct 5. Thing is, thread 1 "alpha" keeps looping until it is halfway within the loop, in this case being 5. Then thread 2 "beta" starts. It is an extrange behaviour I cannont comprehend. What am I missing?
public class synconizedThread implements Runnable {
int balance = 100;
public void run() {
checkAmmount();
}
public void checkAmmount() {
synchronized (this) {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()
+ "checks balance: " + balance);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
withDrawAmmount();
}
}
}
public void withDrawAmmount() {
if (balance <= 0) {
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("Balance is " + balance + " not enough");
}
else {
balance = balance - 5;
System.out.println(Thread.currentThread().getName()
+ "Whitdraws, balance left: " + balance);
}
}
public static void main(String[] args) {
Runnable myJob = new synconizedThread();
Thread alpha = new Thread(myJob);
alpha.setName("alpha");
Thread beta = new Thread(myJob);
beta.setName("beta");
alpha.start();
beta.start();
}
}
You're synchronizing the entire loop, so the first thread enters the loop, then won't give up the CPU until after the loop completes.
Instead, you probably want to synchronize each iteration of the loop, that way the threads will have a chance to alternate.
You're also synchronizing the call to sleep(), which probably isn't what you want to do. You probably want to move that outside your synchronization.
public void checkAmmount() {
for (int i = 0; i < 10; i++) {
synchronized (this) {
System.out.println(Thread.currentThread().getName()
+ "checks balance: " + balance);
withDrawAmmount();
}
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
I see two issues:
The loop is within the synchronized block. So whoever gets that lock first executes the loop. Put the synchronized inside the loop. Then a thread will release the lock at the end of an iteration, and compete for it again at the beginning of the next, and you will have concurrency. For example, make the withDrawAmount() method synchronized. (If you do that, make sure to move the println of thread ID to inside the withDrawAmount().)
Thread.sleep() does not release the lock, so it's not like that fixes the problem of the loop being inside synchronized. You should probably take every Thread.sleep() call out altogether since they're just slowing things down.
As ever, you should try to keep the critical section - the piece inside synchronized - as small as possible, for maximum concurrency. Synchronizing withDrawAmount() should be fine, especially once you get rid of those sleep() calls. If you want to have some fun and try to see if you can get even bigger throughput, take a look at java.util.conccurent.atomic.AtomicInteger
Your first thread enters the synchronized block, loops for 10 iterations and withdraws 5 at each iteration, and then leaves the synchronized block.
So when the 10 iterations are done (and the balance is thus 50), it stops running, leaves the synchronized block, allowing the second thread to run and executes its 10 iterations.
It's the synchronized keyword. You have it around the whole for loop, so whoever gets to it first gets to run the entire for loop.
Thread B can't access the variable while Thread A is using it - it's locked by A.
If you want both to deduct at the same time you should move the synchronized inside the for loop.
As far as I understand your question, your problem is that thread alpha is already halfway through his loop until thread beta starts.
The synchronized keyword blocks all other thread from accesing the synchronized object. You could put the synchronized keyword inside the loop so that each thread enters and then leaves the monitor each time
ALso, by default, threads do not necessarily get the equal cpu time. So thread alpha starts working as soon as you invoke the start() method and is already halfway through until thread "beta" is even started by the main Thread

Two threads, two synchronized blocks and one intrinsic lock

I wrote a code snippet that starts two threads; one thread prints all odd numbers while another thread prints all even numbers.
I used a combination of intrinsic lock and thread communication commands to achieve proper interleaving of my two threads.
Here is my code,
public class threadEvenOdd implements Runnable
{
static Boolean isOdd=true;
int count = 10;
Boolean value;
static int c=1;
static Object lock = new Object();
threadEvenOdd(Boolean temp)
{
value = temp;
}
public void run()
{
if(value)
{
printOdd(count);
}
if(!value)
{
printEven(count);
}
}
void printOdd(int count)
{
try
{
for(int i=0;i<count/2;i++)
{
//System.out.println("odd enters lock");
synchronized(lock)
{
if(!isOdd)
{
//System.out.println("odd in barrier");
lock.wait();
}
System.out.println(c);
c++;
isOdd = false;
//System.out.println("odd notifies");
lock.notify();
}
}
}
catch(Exception e)
{
System.out.println(e);
}
}
void printEven(int count)
{
try
{
for(int i=0;i<count/2;i++)
{
//System.out.println("even enters lock");
synchronized(lock)
{
if(isOdd)
{
//System.out.println("even in barrier");
lock.wait();
}
System.out.println(c);
c++;
isOdd = true;
//System.out.println("even notifies");
lock.notify();
}
}
}
catch(Exception e)
{
System.out.println(e);
}
}
public static void main (String args[])
{
threadEvenOdd th1 = new threadEvenOdd(true);
threadEvenOdd th2 = new threadEvenOdd(false);
Thread t1 = new Thread(th1);
t1.setName("odd");
Thread t2 = new Thread(th2);
t2.setName("even");
//System.out.println(t1.getName() + " starts");
t1.start();
//System.out.println(t2.getName() + " starts");
t2.start();
}
}
Here are my questions:
The odd thread executes in the printOdd() function, while the even thread executes in the printEven() function. I am using one intrinsic lock for both threads; I don't understand how the two threads can exist in their respective synchronized blocks at the same time, because the use the same lock.
I removed the thread communication statements(notify, wait) from my code and still I obtained my desired output. I am now wondering if my code actually needs the thread communication statements at all.
I guess I still need to work on my understanding of multithreading concepts, as I am struggling to understand my own code :p Can anyone explain if there is a better way to do this using only the multithreading concepts that I have used?
Each thread has its own path of execution through the code. Even if two threads run the exact same code they still have two distinct execution points through the code execution through the code. When a thread reaches a synchronized statement it waits for the lock to be available - it will enter the synchronized block only if no other thread is inside a synchronized block guarded by the same lock.
You keep getting the same output although you removed the notify/wait statements can be coincidental. Did you try this with a relatively large value of the count field?
It is kind of hard to answer this question at the moment as you didn't specify what output do you expect this program to produce. Is "1,3,5,7,9,2,4,6,8" a valid output? Is "1,3,2,4,6,5,7,9,8"? Or is "1,2,3,4,5,6,7,8,9" the only valid output? That said, here a few quick points:
Use notifyAll() instead of notify
Minimize the state that is shared between threads. In this case, you share both isOdd and c. Note that the former can be computed from the latter via c % 2 == 1. Thus you can have the thread computing oddness instead of maintaining it as a piece of shared data.
Instead of sharing via static fields create an object (with instance fields) and pass this object to the constructor of each thread. Then you can use the object itself as a lock.
Here's how it can look like:
class SharedData {
int c;
boolean isOdd;
}
class ThreadEvenOdd {
SharedData sharedData;
public ThreadEvenOdd(SharedData sd) { this.sharedData = sd }
// ...
void printOdd(int count) {
try {
for(int i=0;i<count/2;i++) {
synchronized(sharedData) {
if(!sharedData.isOdd) { ... }
System.out.println(sharedData.c);
sharedData.c++;
sharedData.isOdd = false;
lock.notify();
}
}
}
catch(Exception e) {
System.out.println(e);
}
}
}
The nice thing about it is that you can then start defining real methods on sharedData (such as: a method that increases c and set isOdd to the appropriate value based on the value of c thus further simplifying the code in the thread class - and making the synchronization/notification less interleaved with the processing of the data, which makes the code more readable and less prone to errors.

How to (reliably) interrupt threads form the main thread after a specific amount of time in Java?

I just started out with threading. I wrote a main class that sets up and starts 100 threads, waits 5 seconds and then interrupts them (at least that's what I thought it did):
public static void main(String[] args) {
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 100; i++) {
Thread t = new Thread(new Walker());
threads.add(t);
}
System.out.println("Starting threads...");
for (Thread thread : threads) {
thread.start();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// don't do anything
}
System.out.println("Time's up - Terminating threads...");
for (Thread t : threads) {
t.interrupt();
System.out.print(".");
}
for (Thread t : threads) {
try {
t.join(10);
} catch (InterruptedException e) {
// don't do anything
}
}
System.out.println("");
System.out.println("All done.");
}
The threads looked a bit like this:
public class Walker implements Runnable {
public void run() {
for (int i = 0;; i++) {
//do some complicated stuff that takes some time
System.out.println(Thread.currentThread().getName() + ":" + i);
if (Thread.interrupted()) {
break;
}
}
}
}
Now, the output I got was that the main thread began interrupting threads, but some sub threads continued to run a few times (i.e. loop iterations) before terminating, e.g.
Starting threads...
Thread-1:0
Thread-2:0
Thread-1:1
Thread-3:0
[...]
Time's up - Terminating threads...
......Thread-1:60
Thread-1:61
...Thread-1:62
Thread-2:55
..All done.
[output from threads sometimes continued even here - after the join()]
At that time I didn't fully understand that a single thread could be allocated enough processor time to run a few times - I expected at most one additional run before the main thread had the opportunity to interrupt it.
But while I now see that it is absolutely fine for a thread to be executed for some (long) time before the main thread gets a chance to terminate (i.e. interrupt) it, I am still wondering: is there an easy way to interrupt all child threads in a timely manner from the main thread? (Setting a "time to live" through a thread's constructor and then testing inside the Walker class for it is not what I want.)
Also: is it possible for the last print statement to execute and then see some output from individual threads - after all threads were join()ed? (Maybe I have a glitch somewhere else; the actual code is a bit more complex...)
The problem you observe is probably due to how System.out.println works. It is a synchronized method. So a likely explanation is:
when calling System.out.print("."); after t.interrupt();, your main thread acquires the lock to print
before the lock is released, worker threads arrive at System.out.println(Thread.currentThread().getName() + ":" + i); and wait for the lock
when the main thread releases the lock, all the worker threads that were waiting print their progress.
the main thread arrives at System.out.print("."); again and has to wait for the print lock to be available, etc.
Regarding the fact that you see more prints from the worker threads after "All Done" is printed: you only join for 10 ms, so it is possible that it is not enough and a thread is not finished within 10ms of being interrupted. If you just use join() you should not see that any longer.
Example of Worker class that reproduces the behaviour you observe:
class Walker implements Runnable {
public void run() {
for (int i = 0;; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
//do not respond to interruption too quickly on purpose
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + ":" + i);
if (Thread.interrupted()) {
break;
}
}
}
}
It would be easier with ExecutorService, eg
int nThreads = 100;
ExecutorService ex = Executors.newFixedThreadPool(nThreads);
for (int i = 0; i < nThreads; i++) {
ex.execute(new Walker());
}
Thread.sleep(5000);
ex.shutdownNow();
Maybe I have a glitch somewhere else; the actual code is a bit more complex...
Yes it is a glitch, unfortunately isn't a simple set 1 property, java side.
If the code is commercial, complex, than you can allocate a bit more time to write some native libraries, for major Os type. With that help you can easily play with threads as you wanted.
The first times has an overhead for developing and understanding how the threads are woking in native, os side, than just call a function with a few params :)
Not sure, if is helping, the glitch exists.

Categories