Strange java concurrency behavior [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have the following code:
class Hi
{
public static void main (String [] args)
{
int a = 1;
for (int i = 0; i < 50; i++) {
a = a + i;
System.out.println ("a before sleep is " + a);
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
System.out.println ("a after sleep is " + a);
}
}
}
I open two console windows and do java Hi in first one. Then wait for about 10 seconds seconds and do the same in the second window. Both outputs are the same:
a before sleep is 1
a after sleep is 1
a before sleep is 2
a after sleep is 2
a before sleep is 4
a after sleep is 4
a before sleep is 7
a after sleep is 7
a before sleep is 11
a after sleep is 11
with no interleaving. So what's the stir about concurrency issues if I even didn't bother to use synchronized statement? Is it because the code run from different console windows is executed on different processor cores? If so, I've carried out this experiment about 20 times and the results are still the same.

I open two console windows and do java Hi in first one. Then wait for about 10 seconds seconds and do the same in the second window.
You're starting two entirely separate process. That's not using multithreading at all - each process will have its own variables, its own output, everything.
To see multithreading, you need to create threads in a single process. For example:
import java.util.Random;
class Counter implements Runnable {
private int a;
public void run() {
Random random = new Random();
for (int i = 0; i < 10; i++) {
String name = Thread.currentThread().getName();
a++;
System.out.println(name + " Before sleep, a = " + a);
try {
// Add a little more uncertainty...
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
// Ignored
}
System.out.println(name + " After sleep, a = " + a);
}
}
}
public class ThreadingTest {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread t1 = new Thread(counter);
Thread t2 = new Thread(counter);
t1.start();
t2.start();
}
}

You have two different JVM's so two main threads running on two different JVM's so concurrency dont apply.
Yes if you have two threads within same JVM then concurrency applies.

These are two separate processes on your computer. They do not share data or anything else. They are no more related then, for example, your web browser and your wordprocessor. They each have their own separate "a" variable, each completely unrelated to the other.
Concurrency issues arise when multiple threads in the same process space try to access the same variable. That does not apply here.

As here you are running two different processes, no matter how many times you run this code you will get same result. As both of these programs will be running within two separate processes.
To run these programs in multi threaded way you have to implement two threads and start them.

Related

How thread sleep works internally in java? [duplicate]

This question already has answers here:
How Thread.sleep() works internally
(5 answers)
Closed 3 years ago.
It may be a dumb question but i have researched it alot and i am not getting any satisfactory knowledge.
Can anyone help me to understand?
my code
public class sleepclass extends Thread {
public static void main(String[] args) {
sleepclass t1 = new sleepclass();
sleepclass t2 = new sleepclass();
t1.start();
t2.start();
}
public void run() {
for (int i = 1; i < 5; i++) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(i);
}
}
}
Output :
1
1
2
2
3
3
4
4
Now as per the output i can see both thread gone to a sleep state. and both comes after at the same time
My question is :
1 . Since sleep is a static method how both works and sleep at same time? (explain in layman please).
Can i sleep only t1 and left t2 to run?
Thread.sleep() sleeps the current thread. It has no effect elsewhere.
If you want one thread to sleep and one not in your current code, you would have to have some kind of indicator to control it. Such as a boolean flag which you would then check:
if(shouldSleep) {
Thread.sleep(5000);
}
Otherwise all threads will execute the same code, and all threads will sleep for 5 seconds.

Program not always terminating? [duplicate]

This question already has answers here:
Why is i++ not atomic?
(10 answers)
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
I wanted to test out multithreading for a project of mine, trying to also develop a solution in case something goes wrong.
So I made this small test:
main
public class main
{
static int addToCounter;
static int addToErrorCounter;
public static void main(String[] args) throws InterruptedException
{
int threads = 10;
Executor exec = new Executor();
for (int i = 0; i < threads; i++)
{
double error = Math.random();
testClass aldo = new testClass();
Thread thread = aldo.getThread(300, error);
exec.execute(thread);
}
while (threads != (addToCounter + addToErrorCounter))
{
System.out.println("Not all threads finished, number of finished threads is: " + (addToCounter + addToErrorCounter));
Thread.sleep(50);
}
System.out.println("Number of Threads that finished correctly: " + addToCounter);
}
}
testClass
import test1.main;
public class testClass
{
public Thread getThread(long time, double error)
{
Thread thread = new Thread()
{
public void run()
{
try
{
Thread.sleep(time);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (error > 0.5)
{
main.addToErrorCounter++;
throw new java.lang.Error("HELLO");
}
System.out.println("I DID THIS!");
main.addToCounter++;
}
};
return thread;
}
}
(you'll have to fix the imports, also I use a custom class Executor, although that's only a wrapper for ExecutorService)
The weird behaviour is that sometimes it works properly, and sometimes it doesn't (total terminated thread count is 9, although I can see clearly it printed "I DID THIS!" and the error exactly 10 times).
Any fix?
The Problem might be a racecondition.
the "++" operator is not atomic.
Imageine the following scenario. There are two Threads at the same time. both want to increase a number and finish.
The initial value of the number is 0.
Thread 0 reads the number, knows now it is 0.
Thread 1 reads the number, knows now it is 0.
Thread 0 (who knew it was 0) now writes 1 to the memory.
Thread 1 does not know, that the number has changed, and still believes the number is 0 so he also writes a 1 to the memory.
You need something like a synchronizing mechanisim, something like a lock, or a semaphore or something else.
have a look at this for more information: http://winterbe.com/posts/2015/04/30/java8-concurrency-tutorial-synchronized-locks-examples/
for your example you could use the "synchronized" example from that link.
add a method to your main class looking like this to increment the addToCounter and also to the addToErrorCounterto remove the effects from your error counter:
synchronized AddToError(int e){
addToError += e;
}
synchronized IncCounter(){
addToCounter++;
}
call those methods in your threads in the testclass instead of incrementing them unsynchronized.
My guess is that the postfix operator (main.addToCounter++) is not atomic. This line of code is probably equivalent to something like:
int temp = main.addToCounter;
main.addToCounter = temp + 1;
return temp;
With multiple threads doin this at the same time, two threads could obtain the same value for temp (because both peform the first line in the above pseudo-code before either performs the second), and hence the counter total will be too small once all threads are complete. See Why is i++ not atomic? for more information.
A quick fix in this situation is to make addToCounter an AtomicInteger, then use addToCounter.incrementAndGet() in place of addToCounter++.

Why does this empty synchronized block affect the output of the program? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
So I was just messing around with basic concurrency when I noticed the empty synchronized block shown in the program causes the outputs to sync up. There is nothing in the block, so why does it do this?
public class MainClass {
public static void main(String[] args) throws InterruptedException {
SyncTest f = new SyncTest();
f.start();
for (int i = 0; i < 20; i++) {
System.out.println("MAIN THREAD:" + i);
Thread.sleep(500);
synchronized (f) {
for (int t = 0; t < 15; t++) {
Thread.sleep(100);
}
}
}
}
}
class SyncTest extends Thread {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
System.out.println("OTHER THREAD: " + i);
Thread.sleep(1300);
synchronized (this) {} //Why does this have an effect on the output when commented?
} catch (InterruptedException ex) {}
}
}
}
The mechanics of the synchronized can be summed up like this
synchronized(f) { //wait for no-one use f
// do some stuff
//nobdy can use f during this time
} //free f, other can use it
It basically act like if you used a lock, where the lock is f
So even if your block does nothing than waiting, during this wait time f is not available. So it will synchronize your program even if there's only a wait in your block
The execution flow will not enter a synchronized block if the specified lock has already been taken by another thread. This is always the case, even if the synchronized block contains no code at all.
The locks in your example are the same object (the instance of SyncTest.) So while the non-empty synchronized block is running, the empty one will be waiting for it to complete. In this case, because of the way the Thread.sleep() calls line up, it just so happens that the outputs are reasonably likely to be synchronized as a result.
You've got synchronized 2 times by the same object.
First time in the MainClass:
SyncTest f = new SyncTest();
synchronized (f) {...}
Second time in the SyncTest instance itself by "this":
synchronized (this) {}
There are 2 threads in your program: main thread and thread of SyncTest.
Each thread comes to the point of synchronization by SyncTest object and waits until another thread will go out of the synchronization section.
Berry's answer summarizes what synchronized does and mentions that the content of the block does not matter. So the question is not really why the behavior changes, but why it changes so drasticly.
Your threads "sync up" (i.e. log one by one even though otherThread should be a bit faster and sometimes log twice before mainThread) because your mainThread sleeps for a solid 1500ms when blocking the sync object:
synchronized (f)
{
for (int t = 0; t < 15; t++) // this is
{ // (roughly)
Thread.sleep(100); // equivalent to
} // Thread.sleep(1500);
}
That means that mainThread doesn't give otherThread a chance use its speed advantage (1300 ms vs. 1500ms) and makes it wait until it is done sleeping. Change that piece of code to
for (int t = 0; t < 15; t++)
{
synchronized (f)
{
Thread.sleep(100);
}
}
and otherThread will slide right into one of those breaks between the 100ms naps and the empty sync block is not affecting anything much anymore.
Note that the empty sync block still has a little effect and might change the order of the logs a bit because otherThread might still have to wait a little (but only a maximum 100ms instead of 1500ms). It won't result in such a strict back-and-fourth anymore, though.

Compiler ignore threads priorities

I tried to compile the example from Thinking in Java by Bruce Eckel:
import java.util.concurrent.*;
public class SimplePriorities implements Runnable {
private int countDown = 5;
private volatile double d; // No optimization
private int priority;
public SimplePriorities(int priority) {
this.priority = priority;
}
public String toString() {
return Thread.currentThread() + ": " + countDown;
}
public void run() {
Thread.currentThread().setPriority(priority);
while(true) {
// An expensive, interruptable operation:
for(int i = 1; i < 100000; i++) {
d += (Math.PI + Math.E) / (double)i;
if(i % 1000 == 0)
Thread.yield();
}
System.out.println(this);
if(--countDown == 0) return;
}
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++)
exec.execute(
new SimplePriorities(Thread.MIN_PRIORITY));
exec.execute(
new SimplePriorities(Thread.MAX_PRIORITY));
exec.shutdown();
}
}
According to the book, the output has to look like:
Thread[pool-1-thread-6,10,main]: 5
Thread[pool-1-thread-6,10,main]: 4
Thread[pool-1-thread-6,10,main]: 3
Thread[pool-1-thread-6,10,main]: 2
Thread[pool-1-thread-6,10,main]: 1
Thread[pool-1-thread-3,1,main]: 5
Thread[pool-1-thread-2,1,main]: 5
Thread[pool-1-thread-1,1,main]: 5
...
But in my case 6th thread doesn't execute its task at first and threads are disordered. Could you please explain me what's wrong? I just copied the source and didn't add any strings of code.
The code is working fine and with the output from the book.
Your IDE probably has console window with the scroll bar - just scroll it up and see the 6th thread first doing its job.
However, the results may differ depending on OS / JVM version. This code runs as expected for me on Windows 10 / JVM 8
There are two issues here:
If two threads with the same priority want to write output, which one goes first?
The order of threads (with the same priority) is undefined, therefore the order of output is undefined. It is likely that a single thread is allowed to write several outputs in a row (because that's how most thread schedulers work), but it could also be completely random, or anything in between.
How many threads will a cached thread pool create?
That depends on your system. If you run on a dual-core system, creating more than 4 threads is pointless, because there hardly won't be any CPU available to execute those threads. In this scenario further tasks will be queued and executed only after earlier tasks are completed.
Hint: there is also a fixed-size thread pool, experimenting with that should change the output.
In summary there is nothing wrong with your code, it is just wrong to assume that threads are executed in any order. It is even technically possible (although very unlikely), that the first task is already completed before the last task is even started. If your book says that the above order is "correct" then the book is simply wrong. On an average system that might be the most likely output, but - as above - with threads there is never any order, unless you enforce it.
One way to enforce it are thread priorities - higher priorities will get their work done first - you can find other concepts in the concurrent package.

Java Thread Ping Pong example Issue

I have seen the example of PingPong using synchronized keyword.Basicly the actual example is this:
public class PingPong implements Runnable {
synchronized void hit(long n) throws InterruptedException {
for (int i = 1; i < 3; i++)
System.out.print(n + "-" + i + " ");
}
public static void main(String[] args) {
new Thread(new PingPong()).start();
new Thread(new PingPong()).start();
}
public void run() {
try {
Long id = Thread.currentThread().getId();
hit(id);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Normally the hit method is not synchronized because the synchronized keyword will work only if there is one object.So the result can be like 8-1 9-1 8-2 9-2 or 8-1 9-1 9-2 8-2...(It's a randomly result).But in this example it give us all time 8-1 8-2 9-1 9-2 which is a little bit strange because that mean that the hit method is synchronized!!!.
I have modified the code to check again that the hit method must be not sycnhronized so i add a Thread.sleep(1000) at the starting of the hit method it will be like
synchronized void hit(long n) throws InterruptedException {
Thread.sleep(1000);
for (int i = 1; i < 3; i++)
System.out.print(n + "-" + i + " ");
}
Now the code is giving random result each time i make an execution.
I'm really getting confusing!!
Can some one help me in understanding this issue ?
You do indeed have two separate instances of PingPong, which would mean that there would be two separate monitor objects, which should mean that the threads are not being forced to run synchronously.
I think that you are probably running into thread scheduling behavior. On a single core CPU, the code may very well execute as you describe because the thread scheduler is never given a chance to take over.
If you add a sleep to your for loop:
synchronized void hit(long n) throws InterruptedException {
for (int i = 1; i < 3; i++){
System.out.print(n + "-" + i + " ");
Thread.sleep(0);
}
}
That should release the scheduler to run other threads. Note that the JVM doesn't provide any guarantees of how the scheduler will actually behave, but in my experience the above is sufficient.
If you are on a multi-core CPU, I'd expect it to work as you expected without the sleep() call.
Not sure what is meant by synchronization. Do you want to mean that the threads are being picked up by the thread scheduler in a particular order always? If yes, that is not true. Just increase "i" from 3 to a higher value, say 10. I am seeing the following output :
12-1 11-1 12-2 11-2 12-3 11-3 12-4 11-4 12-5 11-5 12-6 11-6 12-7 11-7 12-8 12-9 11-8 11-9
Well, I have multi-core processor, hence multiple threads at the same point of time. I guess that should be the case even for you.

Categories

Resources