Thread2 waits Thread1 to complete to start Problem? Java - java

So I have a simple code that I want to print the value I 10 times with Thread1, after that 10 times of Thread2 and at the end, print the count ( it should be 20). I am using the ".join()" but the result is executing random times of Thread1 and Thread2 and then the Sum is correct. How can is it possible to print first all the Thread's1 loop and then the Tread's2 ??
class MyClass extends Thread {
public static synchronized void incount() {
SimpleThreads.count++;
}
public void run() {
for(int i=0; i<10; i++) {
incount();
System.out.println(Thread.currentThread().getId()+" value : " + i);
}
}
}
public class SimpleThreads {
static int count=0;
public static void main(String[] args) {
MyClass thread1 =new MyClass();
MyClass thread2 =new MyClass();
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" Sum : "+count);
}
}
The Result :
11 value : 0
10 value : 1
11 value : 1
10 value : 2
11 value : 2
10 value : 3
11 value : 3
11 value : 4
11 value : 5
11 value : 6
11 value : 7
11 value : 8
11 value : 9
10 value : 4
10 value : 5
10 value : 6
10 value : 7
10 value : 8
10 value : 9
Sum : 20

You are starting Thread2 before calling the join() on thread1.
That is why your both threads are basically running simultaneously and your join is not affecting the run() of any other the 2 threads.
Try to change your start and join calling code to something like this;
try{
thread1.start();
thread1.join();
thread2.start();
}
You shouldn't need to call join() on thread2 in this case.

If you want thread2 to start after thread1 terminates, then of-course you can simply wait for thread1 to terminate and then launch thread2. But then, what is the point of using threads?
If you want to launch thread1 and thread2 at the same time and still have thread2 wait until thread1 terminates, you can use one of Java's many concurrency utilities, such as Semaphore
The below code demonstrates the use of Semaphore. As you can see, just as in the code in your question, both threads - thread1 and thread2 - are launched at the same time. In the run() method of class MyClass, the code tries to acquire the semaphore. Method acquire() will block, i.e. it will not return, until it succeeds in acquiring the semaphore. Hence the first thread that manages to acquire the semaphore will run, while the other thread will wait until the first thread releases the semaphore. Note that I create the semaphore with only one permit which means that only one thread can acquire the semaphore at any one time. If you change the 1 to a 2 in the call to the Semaphore constructor, you will get exactly the same behavior as in your original code in your question, i.e. both threads will run simultaneously because both can immediately acquire the semaphore.
Note also that since I am using a semaphore, I don't need to call Thread.join() at all in order to have one thread wait until the other completes, but since you want to print the "sum" in the "main" thread, the "main" thread needs to wait, but it only needs to wait for the second thread to terminate.
Here is the code:
import java.util.concurrent.Semaphore;
class MyClass extends Thread {
private Semaphore semaphore;
public MyClass(Semaphore semaphore) {
this.semaphore = semaphore;
}
public static synchronized void incount() {
SimpleThreads.count++;
}
public void run() {
try {
semaphore.acquire();
for (int i = 0; i < 10; i++) {
incount();
System.out.println(Thread.currentThread().getId() + " value : " + i);
}
}
catch (InterruptedException xInterrupted) {
xInterrupted.printStackTrace();
}
finally {
semaphore.release();
}
}
}
public class SimpleThreads {
static int count = 0;
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(1);
MyClass thread1 = new MyClass(semaphore);
MyClass thread2 = new MyClass(semaphore);
thread1.start();
thread2.start();
try {
thread2.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" Sum : " + count);
}
}
And here is the output obtained when running the above code:
13 value : 0
13 value : 1
13 value : 2
13 value : 3
13 value : 4
13 value : 5
13 value : 6
13 value : 7
13 value : 8
13 value : 9
14 value : 0
14 value : 1
14 value : 2
14 value : 3
14 value : 4
14 value : 5
14 value : 6
14 value : 7
14 value : 8
14 value : 9
Sum : 20

Related

Synchronized Thread in Java

I have 3 class like this:
Source.java
public class Source extends Thread{
private int x= 0;
public void increment(int id){
x++;
System.out.println(id+" "+x);
}
}
Task.java
public class Task extends Thread{
private Source source;
private int id;
public Task(Source source, int id){
this.source=source;
this.id=id;
}
public void run(){
for (int i=0;i<100;i++){
try{Thread.sleep(1000);}catch(InterruptedException e){}
source.inc(id);
}
}
}
Main.java
public class Main{
public static void main(String[] args) throws IOException{
Source source = new Source();
Task t1=new Task(source,1);
Task t2=new Task(source,2);
t1.start();
t2.start();
}
}
I want when the x of the class Source will be equal to 4 only one task continues to increment x until x is equal to 8, we return to normal.
The result will look like this:
1 1
2 2
1 3
2 4
1 5
1 6
1 7
1 8
1 9
1 10
2 11
1 12
2 13
...
How do I modify the code to achieve the desired result?
Basically you have two threads that modify the same variable x. There is no garantee about the order of execution.
You should synchronize.
With your current implementation you may face a problem (The race condition problem): Race condition example
Something like this is an scenario that most likely is going to happen to you:
....
1 3
2 4
2 5
1 6
1 7
2 7
1 8
2 9
1 10
2 10
...
As you can see the thread 2 (source 2) tries to increment the variable x when the variable has been already incremented but the value it has to increment is the old one.
x = 0
Thread 1 reads the variable x (0)
Thread 2 reads the variable x (0)
Thread 1 increments variable x + 1 (0 + 1) = 1
Thread 2 increments variable x + 1 (0 + 1) = 1
In order to solve this you need to synchronize your variable, an AtomicInteger would be enough. + I don't think you need the extends Thread on your Source class, you can get rid of it

System.out.println with java volatile

I have an example like that:
public class MainApp {
private volatile static int MY_INT = 0;
public static void main(String[] args) {
new Thread1().start();
new Thread2().start();
}
static class Thread1 extends Thread {
#Override
public void run() {
while(true) {
MY_INT++;
System.out.println("1 : " + MY_INT);
}
}
}
static class Thread2 extends Thread{
#Override
public void run() {
while(true) {
MY_INT++;
System.out.println("2 : " + MY_INT);
}
}
}
}
And the output is:
1 : 1
2 : 2
1 : 3
2 : 4
1 : 5
1 : 7
1 : 8
1 : 9
1 : 10
2 : 6
1 : 11
1 : 13
I don't understand why after printing 1:10 and the next line is 2:6. Can anyone explain the result? Thanks in advance
There are several issues here:
threads may not run in parallel. They run in time slices (default: 15.6 ms on a PC; 64 ticks per second, see timer resolution (Microsoft)). This is why you don't see 1:x and 2:x one after another, but several 1:x after each other.
using volatile does not help with synchronization. You need real synchronization objects such as AtomicInteger or the synchronized keyword. Therefore you may see skipped numbers (not the case in your output, but it may occur). You need the synchronization around both, the ++ and the println() if you want to see unique numbers
Console output is buffered and synchronized, because you don't want 2 println statements to mix the output on one line
The PrintStream in System.out and the volatile field MY_INT are independently synchronized, so the following can happen:
Thread 1 Thread 2
read MY_INT = 4
write MY_INT = 5
read MY_INT = 5
read MY_INT = 5
write MY_INT = 6
read MY_INT = 6
println 5
read MY_INT = 6
write MY_INT = 7
read MY_INT = 7
println 7
...
println 6
That is, because the volatile field and the PrintStream returned by System.out are independently synchronized, printing may occur in non-ascending order.
The following could also happen:
Thread 1 Thread 2
read MY_INT = 1
read MY_INT = 1
write MY_INT = 2
write MY_INT = 2
read MY_INT = 2
println 2
read MY_INT = 2
println 2
because ++MY_INT is actually compiled into a read, a computation, and a write. Since volatile reads and writes are separate synchronization actions, other threads may act in between, and mess the counter up.
If you want ascending numbers being printed by separate threads, the easiest way is:
void run() {
while (true) {
synchronized (lock) {
MY_INT++;
System.out.println("1 : " + MY_INT);
}
}
}
where lock is an object shared by all threads accessing MY_INT.

Why are my threads giving me this output when accessing a synchronized method?

I'm trying to experiment on multithreading and synchronization, so I have created this simple object that is shared between all threads:
public class SharedObject {
private int count = 0;
public synchronized int getCount(){
return count;
}
public synchronized void incrementCount(){
count++;
}
}
And it's accessed by 3 threads in this manner:
public static void main(String[] args) throws Exception {
SharedObject sharedObject = new SharedObject();
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
Runnable task = () -> {
for(int i = 0; i < 10; i++){
System.out.println("Thread : " + Thread.currentThread().getName()
+ " count : " + sharedObject.getCount());
sharedObject.incrementCount();
try{
Thread.currentThread().sleep(2000);
}
catch (Exception e){}
}
};
executor.submit(task);
executor.submit(task);
executor.submit(task);
executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);
System.out.println("Final : " + sharedObject.getCount());
}
My output is the following :
Thread : pool-1-thread-2 count : 0
Thread : pool-1-thread-1 count : 0
Thread : pool-1-thread-3 count : 0
Thread : pool-1-thread-3 count : 3
Thread : pool-1-thread-2 count : 3
Thread : pool-1-thread-1 count : 3
Thread : pool-1-thread-2 count : 6
Thread : pool-1-thread-1 count : 6
Thread : pool-1-thread-3 count : 6
...
If my understanding is correct (please correct me if i's wrong), this is happening because:
The first thread calls getCount(), gets the lock on the method, and as soon as he prints the count value, releases the lock which is then acquired by the second thread to call getCount(), and onward with the last thread
When all 3 threads are done calling getCount(), each of them is now calling incrementCount() and since the method is synchronized, each thread sees the updated value before incrementing the count, which explains why we see jumps of +3 in the output
As soon as a thread finishes , it calls sleep(2000) on itself, but since the calls are so fast, it seems like the three threads start and stop to sleep at the same time
However, when i remove sleep(2000), i get the following output:
Thread : pool-1-thread-3 count : 0
Thread : pool-1-thread-2 count : 0
Thread : pool-1-thread-1 count : 0
Thread : pool-1-thread-2 count : 2
Thread : pool-1-thread-3 count : 1
Thread : pool-1-thread-2 count : 4
Thread : pool-1-thread-1 count : 3
Thread : pool-1-thread-2 count : 6
Thread : pool-1-thread-3 count : 5
Thread : pool-1-thread-2 count : 8
Thread : pool-1-thread-1 count : 7
Thread : pool-1-thread-2 count : 10
Thread : pool-1-thread-3 count : 9
Thread : pool-1-thread-2 count : 12
Thread : pool-1-thread-1 count : 11
Thread : pool-1-thread-2 count : 14
And i don't understand how this can happen. For example, how can thread-3 see the count being equal to 1 if thread-2 saw it equal to 2 before him and incremented it ?
Any explanation would be appreciated to help me better understand Java in a multithreaded synchronized environment. Thank you for your time.
Remember that the ouput on your screen might not have anything to do with the order of execution of getCount()/incrementCount(), there's no locking in the code that prints the output.
For example, how can thread-3 see the count being equal to 1 if thread-2 saw it equal to 2 before him and incremented it ?
This output can occur if you have these order of execution:
Thread-3 calls getCount() and it returns 1.
Thread-1 calls incrementCount()
Thread-2 calls getCount() and it returns 2.
Thread-2 calls System.out.println that prints: "pool-1-thread-2 count : 2"
Thread-3 calls System.out.println that prints: "pool-1-thread-3 count : 1"
Just because a thread reads a value before another one doesn't mean it will print it before the other one. Yo would need the read and the print to be done atomically, inside the synchronized block, to have that guarantee.
So what you can have is thus
thread 3 reads and prints the value (0):
Thread : pool-1-thread-3 count : 0
thread 2 reads and prints the value (0):
Thread : pool-1-thread-2 count : 0
thread 1 reads and print the value (0):
Thread : pool-1-thread-1 count : 0
thread 3 increments the value (1)
thread 3 reads the value (1)
thread 2 increments the value (2)
thread 2 reads and prints the value (2):
Thread : pool-1-thread-2 count : 2
thread 3 prints the value it has read before:
Thread : pool-1-thread-3 count : 1
In your SharedObject, the individual getCount and incrementCount methods are synchronized, but nothing prevents all three threads from calling getCount (one at a time) before any of them calls incrementCount. And then again after each sleep. That's what your first output is showing.
Without the sleep() it is furthermore possible for for one thread to call getCount() more than once before one or more of the others calls incrementCount() even once. Technically it's not forbidden even with the sleep. Likewise, it is possible for one thread to get, increment, and print getween when another gets and when it prints. These kinds of orderings explain why your output without the sleep is not sequential.
If you want to see sequential output without skips, then you need more broadly-scoped synchronization. For example, in your task implementation you might use a synchronized block:
synchronized (sharedObject) {
System.out.println("Thread : " + Thread.currentThread().getName()
+ " count : " + sharedObject.getCount());
sharedObject.incrementCount();
}
Each time a thread enter s the synchronized block, it will get the count, print it, and increment it without any of the other threads doing any of those things in between.

Threads and Synchronization in java

Consider the below code for Thread Synchronization Method and a Synchronization Block
public class ThreadSynchronizationPartI {
public static int myValue=1;
public static void main(String [] args)
{
Thread t=new Thread(()->
{
while(true)
{
updateBalance();
}
});
t.start();
t=new Thread(()->{
while(true)
{
monitorBalance();
}
});
t.start();
}
public static synchronized void updateBalance(){
System.out.println("start "+myValue);
myValue = myValue + 1;
// myValue = myValue - 1;
System.out.println("end "+myValue);
}
public static synchronized void monitorBalance(){
int b=myValue;
if(b>1)
{
System.out.println("B is greater than 1 by"+(b-1));
System.exit(1);
}
}
}
Why Does it give the following output:
start 1
end 2
start 2
end 3
start 3
end 4
start 4
end 5
start 5
end 6
start 6
end 7
start 7
end 8
B is greater than 1 by 7
Can anyone explain?
The execution of your program will start from main(). Initially the value of myValue is 1 and a new thread t will be created. Until the condition is true the while loop will be executed. When the control will reach updateBalance(), it will jump to that method and the println() will print the value of myValue which is 1. Hence the output will be : start 1 it will then increase the value of myValue to +1 and as a result the next println() would print the output as : end 2. When the condition for next thread will be true in while loop, the control will be transferred there. The monitorBalance() will be called and b is initialized the value of myValue. When the condition b>1 evaluates to true it will print : B is greater than 1 by (b-1).

Explainanton needed for multithreded java program execution

I am trying to learn multi-threading in java. I wrote this sample code, to get a random number and exit if the number is positive integer. Here I am using synchronized just to check how it works. Since the method gererateRandom() is synchronized my expectation is that only one thread is allowed to go inside the function. Although there is no shared variable I am just checking how it works.
The program is working fine, but what I am expecting is, as the thread gets a positive number it should exit the program and other threads should be blocked. But the result I am getting is completely different. Please check the result section below the code.
import java.util.Random;
public class CheckNumbnerThread implements Runnable{
Thread t;
int n ;
CheckNumbnerThread() {
t = new Thread(this);
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
#Override
public void run() {
gererateRandom();
}
public synchronized int gererateRandom(){
Random rn = new Random();
n = rn.nextInt() % 100;
System.out.println("The random number generated is " + n);
if (n > 0){
System.exit(0);
}
return n;
}
}
public class DemoThread {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int counter = 0;
while(true){
new CheckNumbnerThread();
counter++;
System.out.println("Thread counter " + counter);
}
}
}
Child thread: Thread[Thread-0,5,main]
Thread counter 1
Child thread: Thread[Thread-1,5,main]
The random number generated is 79
Thread counter 2
Child thread: Thread[Thread-2,5,main]
The random number generated is 27
Thread counter 3
Child thread: Thread[Thread-3,5,main]
The random number generated is -7
Thread counter 4
Child thread: Thread[Thread-4,5,main]
The random number generated is -68
Thread counter 5
Child thread: Thread[Thread-5,5,main]
The random number generated is 20
Thread counter 6
Child thread: Thread[Thread-6,5,main]
The random number generated is 67
Thread counter 7
Child thread: Thread[Thread-7,5,main]
The random number generated is 13
Thread counter 8
Child thread: Thread[Thread-8,5,main]
The random number generated is 56
Thread counter 9
Child thread: Thread[Thread-9,5,main]
The random number generated is 93
But what I expected is that it should stop execution after printing:
Child thread: Thread[Thread-0,5,main]
Thread counter 1
Child thread: Thread[Thread-1,5,main]
The random number generated is 79
Your synchronized applies to the instance of that thread only and will not prevent the method running in parallel on multiple threads like your code does. If you want to synchronize on all instances, synchronize on class.
synchronized (CheckNumbnerThread.class) {
n = rn.nextInt() % 100
// ...
}
that's not the idea. since you've synchronized the method gererateRandom(), what you're assuring is that no more than one thread will execute this method at the same time.
but since there's no restriction for this method execution, what is happening is that all your threads will just wait for their time to execute this method, but all of them will be executed.

Categories

Resources