public class Test extends Thread{
public void hello(String s){
System.out.println(s);
}
public void run(){
hello("I’mrunning...");
}//endofrun()
public static void main(String [] args){
Test t=new Test();
System.out.println("always first");
t.start();
System.out.println("always second but why?");
}
}
I've run that chunk of code 30 times.
Why is "always second but why?" always second on the console? When t.start() is called, we have 2 threads. (2 stacks): the main thread and the second thread. so "i'am running" has to be sometimes the second output on the console. When i delete the "always first" output statement than the two outputs left, behave non deterministic (that's the way it should be)
so what is wrong in my thinking, why is System.out.println("always first"); influencing the concurrency?
By writing something out to the console first, you may well be affecting when JIT compilation occurs and possibly even type initialization occurs. I don't find it completely unbelievable that something like this changes the observed ordering. I wouldn't be surprised to see the program behave slightly differently on different systems and with different JVMs.
The thing is, either of those orderings is completely valid. You shouldn't rely on it being one or the other, and it's not a bug if it always happens the same way. (Or rather, it might be - but it doesn't have to be.)
If you want to ensure a particular order, you need to do that explicitly - if you don't mind what order things happen in, then there's no problem :)
I've run that chunk of code 30 times.
Run it another seven billion times on every OS and hardware combination possible and report your findings then. 30 is a very low value of forever.
Why is "always second but why?" always second on the console?
How many cores do you have? Most thread schedulers will favour the currently running thread over a newly spawned one, especially on single cores, and will favour synchronizing threads between cores at as late a point as possible (the thread object and System.out needs to be passed between the OS threads).
Given threading is not deterministic and most OS don't guarantee fairness nor timeliness, it's not in any way a bug that it behaves in this way.
If you want an explicit ordering between the threads, then you should use either syncronized blocks or the more powerful classes in java.util.concurrent. If you want non-deterministic behaviour, but to allow the other thread to run, you can give a hint to the scheduler using Thread.yield().
public static void main ( String [] args )
{
FirstThreadBug t = new FirstThreadBug();
System.out.println ( "always first" );
t.start();
yield();
System.out.println ( "always second but why?" );
}
Why is "always second but why?" always second on the console?
It's not always second. I managed to produce both orderings in about 5 executions of your code. Both orderings are valid, and thread scheduling depends on your OS, and possibly JVM and hardware as well.
so what is wrong in my thinking, why is System.out.println("always first"); influencing the concurrency?
Your thinking is right, your experiments are misleading you ;)
System.out.println("always first") will always come first, because it comes before the 2nd thread starts, so it will never effect the concurrency.
try placing "always first" sentence after t.start();, you may get what you're expecting :)
Related
As shown in the code, locksupport.park () is called twice in thread t1. After LockSupport.park () for the first time, the main Thread wakes up Thread t1 with t1.interrupt() and then calls thread.interrupted () in t1 to clear the interrupted status of the thread. But Locksupport.park () does not suspend the thread a second time. Oddly enough, After comment out the [log.debug("test.......")], locksupport.park () can pause the thread a second time. What is the reason for this?
enter image description here
enter image description here
#Slf4j
public class Test08Park4 {
public static void main(String[] args) throws InterruptedException{
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
LockSupport.park();
/**
* With this log print, locksupport.park () cannot stop threads;
* If you comment this out, locksupport.park () can stop the thread
*/
log.debug("test.......");
Thread.interrupted();
LockSupport.park();
log.debug("finished...");
}
});
t1.start();
sleep(1000);
t1.interrupt();
}
}
if do not comment [log.debug("test.......")] out,the result:
22:37:05.435 [Thread-0] DEBUG test.Test08Park4 - test.......
22:37:05.439 [Thread-0] DEBUG test.Test08Park4 - finished...
if comment [log.debug("test.......")] out,the result:
//nothing
Reading docs is fundamental.
As the docs indicate, LockSupport.park() is allowed to spuriously return. In other words, the docs literally spell out:
Q: "Why did the park() call return so quickly?"
A: Because the JVM felt like it.
LockSupport's locks are thread-global. There is exactly one semaphore (which LockSupport calls a 'permit') for each thread, you can't make more and you can't make less. Basically meaning, exactly one system within your JVM can use it, because if two use it, they confuse each other.
As the docs also say:
Basic thread blocking primitives for creating locks and other synchronization classes.
Which in essence means: Why are you doing this? If you want locking behaviour, use e.g. ReentrantLock from the java.util.concurrent package; this isn't meant for you, and hence it has all sorts of bizarre weirdness in it, such as park()'s rule that it is allowed spurious returns.
Most likely the log.debug code either [A] ends up calling LockSupport.unpark(ownThread) for some reason, which means the next park() call returns immediately, or [B] it's a timing matter. log.debug is not 'free', many log frameworks run 'in-place', meaning, the log.debug call actually goes out on disk and fsyncs, meaning, it takes a very long time indeed compared to your average non-disk-interacting java instruction (hundreds of instructions worth of time). That time is enough for the scheduler to fly by it, especially considering 'write to disk' or 'fsync' is a natural stopping point (threads in java are pre-emptive, but if you give the scheduler an excuse to pause your thread, it will usually take it).
In the end, the docs are clear: You don't get an answer to your 'why' question. The specs give the JVM free reign not to have to explain to you why park() spuriously returns. Therefore there isn't much point chasing down the why for this case - even if you have an answer, tomorrow there can be a different reason. If your code can't handle spurious returns on LockSupport.park(), your code is by definition broken. Even if you can make it work on your machine, today, with this phase of the moon, then that's no guarantee it would work fine tomorrow.
Once your code can handle spurious returns, figuring out why it spuriously returns here isn't interesting anymore. Thus, solution: Deal with spurious returns properly. Or, more likely, don't use this for locks, use something more friendly to end users.
Each Java thread is mapped to a kernel thread in Windows and in Windows the time slice for thread switching is 10-100ms.
However, from the result of the following simple codes, it seems each thread switches the CPU resource every line of code. Why?
class MyThread extends Thread{
public MyThread(String name){
super(name);
}
public void run(){
for(int i=0;i<5;i++){
System.out.println( this.getName()+":"+i);
}
}
public static void main(String args[]){
Thread p = new MyThread("t1");
p.start();
for(int i=0;i<5;i++){
System.out.println( "main:"+i);
}
}
}
First of all, you don't tell us what output you are seeing and what you are expecting to see. So it is not possible to explain the former, or why the latter may be off-base.
However, there are a number of factors that could explain why the output is different to what you expect.
The output is likely to depend on the number of cores (or hyperthreads) on your system. And the number of them that the OS makes available to your Java application.
If there are higher priority threads running in the Java application itself or in other parts of the system, that will perturb time slicing. (A low priority thread's time-slice may be cut short if a high priority thread needs to be scheduled.)
Java thread rescheduling doesn't just occur due to time slicing. It can also happen when a thread does blocking I/O, or when it attempts to acquire a Lock or a mutex, or wait(...) or sleep(...) or something similar.
System.out.println has some hidden synchronization going on behind the scenes so that two threads printing at the same time don't cause corruption of the shared buffer data structures.
In short, whatever output you see from that program, it will not be clear evidence of time slicing behavior. (And my guess is that it is not evidence of any significance at all.)
But the answer to your question:
How long does a Java thread own a CPU time slice?
is that it is not possible to predict, and would be very difficult to measure.
System.out.println is a blocking operation that takes a lot of time compared to everything else you're doing. It's also synchronized so that only one thread can print a line at a time.
This causes the alternating behaviour you're seeing. While one thread is printing, the other one has plenty of time to get ready to print, call println, and wait for the first thread to complete. When the first thread finishes printing, the second one gets to print, and the first one will be back waiting for it to finish before it's done.
For example :
public class Example1 {
public static void main(String[] args) {
Loop loop = new Loop();
loop.start(); //printing "Before start"
System.out.println("After start");
}
}
Can be a situation that the loop's run method finishes before the execution of the last line that prints "After Start"?
Once you start multi-threading, you would be wise to drop all assumptions you have about the order in which threads will run.
If it's important, you can use synchronizing operations but, without them, all bets are off.
Yes, you have no control over how the threads are executed/scheduled by the JVM.
If you want to introduce some kind of ordering (execute the two threads in sequence) the most straightforward way to do it would be to use one of the Lock objects that Java provides.
You are basically asking about thread safety in Java (at least that is what I am understanding from the question). As one of the earlier answers already stated it is a good idea to drop any assumptions you may have about execution order when running multiple threads.
However(!), it is possible to use design principles and critical thinking to model your application in such a way that no undesired side effects can occur as a result of multi-threading.
For starters you can read this article on Designing Object Initilization
The gist of the article is that you should think of your classes as finite state machines. If you don't know what they are: finite state machines operate in a set of states (hence the name).
The idea is that when you are in state (A) you can define the behavior that this specific state can perform: (A) -> (B), (A) -> (C)
I can go from state (A) to state (B) and (C) but not to state (D) (should it exist) This mindset is important to understand what your application CAN do in any given situation. (Fine State Machines Wikipedia)
Once you understand this you can move onto
The Fix:
There are three ways to make an object thread safe:
Synchronize critical sections
Make it immutable
Use a thread-safe wrapper
Each approach has it's own advantages/disadvantages that are explained in Java documentation here:
Synchronize
Immutables
Wrappers
Hopefully this will have given you a better understanding of the complications you can face when creating multi-threaded applications.
If I add a join on the thread and a few more print statements then some of the characteristics can be explained.
public class Example1 {
public static void main(String[] args) {
Loop loop = new Loop();
System.out.println("Before start");
loop.start(); //printing "Before start"
System.out.println("After start");
loop.join();
System.out.println("After join");
}
}
"Before start" will always be printed before loop.run() gets executed.
"After join" will always be printed after loop.run() is finished.
"After start" has no guarantee about when it is printed relative to the loop.run(); it can be before, it can be after, it can be during execution interleaved with print statements in loop.run().
If you do want guarantees then you need other synchronization utilities like locks and semaphores.
If I have the following dummy code:
public static void main(String[] args) {
TestRunnable test1 = new TestRunnable();
TestRunnable test2 = new TestRunnable();
Thread thread1 = new Thread(test1);
Thread thread2 = new Thread(test2);
thread1.start();
thread2.start();
}
public static class TestRunnable implements Runnable {
#Override
public void run() {
while(true) {
//bla bla
}
}
}
In my current program I have a similar structure i.e. two threads executing the same Run() method. But for some reason only thread 1 is given CPU time i.e. thread 2 never gets a chance to run. Is this because while thread 1 is in its while loop , thread 2 waits?
I'm not exactly sure, if a thread is in a while loop is it "blocking" other threads? I would think so, but not 100% sure so it would be nice to know if anyone could inform me of what actually is happening here.
EDIT
Okay, just tried to make a really simple example again and now both threads are getting CPU time. However this is not the case in my original program. Must be some bug somewhere. Looking into that now. Thanks to everyone for clearing it up, at least I got that knowledge.
There is no guarantee by the JVM that it will halt a busy thread to give other threads some CPU.
It's good practice to call Thread.yield();, or if that doesn't work call Thread.sleep(100);, inside your busy loop to let other threads have some CPU.
At some point a modern operating system will preempt the current context and switch to another thread - however, it will also (being a rather dumb thing overall) turn the CPU into a toaster: this small "busy loop" could be computing a checksum, and it would be a shame to make that run slow!
For this reason, it is often advisable to sleep/yield manually - even sleep(0)1 - which will yield execution of the thread before the OS decides to take control. In practice, for the given empty-loop code, this would result in a change from 99% CPU usage to 0% CPU usage when yielding manually. (Actual figures will vary based on the "work" that is done each loop, etc.)
1The minimum time of yielding a thread/context varies based on OS and configuration which is why it isn't always desirable to yield - but then again Java and "real-time" generally don't go in the same sentence.
The OS is responsible for scheduling the thread. That was changed in couple of years ago. It different between different OS (Windows/Linux etc..) and it depends heavily on the number of CPUs and the code running. If the code does not include some waiting functionality like Thread.yield() or synchhonized block with a wait() method on the monitor, it's likely that the CPU will keep the thread running for a long time.
Having a machine with multiple CPUs will improve your parallelism of your application but it's a bad programming to write a code inside a run() method of a thread that doesn't let other thread to run in a multi-threaded environment.
The actual thread scheduling should be handled by the OS and not Java. This means that each Thread should be given equal running time (although not in a predictable order). In your example, each thread will spin and do nothing while it is active. You can actually see this happening if inside the while loop you do System.out.println(this.toString()). You should see each thread printing itself out while it can.
Why do you think one thread is dominating?
I saw the following example on the internet:
public class TwoThreads {
public static class Thread1 extends Thread {
public void run() {
System.out.println("A");
System.out.println("B");
}
}
public static class Thread2 extends Thread {
public void run() {
System.out.println("1");
System.out.println("2");
}
}
public static void main(String[] args) {
new Thread1().start();
new Thread2().start();
}
}
My question is :
It is guarantee that "A" will be printed Before "B" and "1" will be printed before "2", but is it possible that "1" will be printed twice successively by another thread?.In this piece of code we have at least 3 threads(1 main and 2 created). can we imagine the scheduler runs 1 thread: new Thread1().start(); then gave up immediately after System.out.println("1"); then again run another threat in Thread1().start(); that prints "1" again ?
I am using NetBeans IDE, it seems running such a program always lead to the same first result, so it seems there something with caching. From my understanding you deal with that with declaring volatile variables, can it be done here,how ? if not then what is the solution for caching ?
In today's Computer's processor, we mostly have 2 processors,and still we find many multi-threading programs on the net uses more than 2 threads! isn't this process becomes heavy and slow regarding compiling ?
1) There is no guarantee in what order the threads will proceed.
2) The order is not randomized, either, though. So if you run the program under identical (or very similar) conditions, it will probably yield the same thread interleaving. If you need to have a certain behaviour (including randomized behaviour) you need to synchronized things yourself.
3) A CPU with two cores can only run two threads at the same time, but most threads spend most of their time not actually using the CPU, but waiting for something like I/O or user interaction. So you can gain a lot from having more than two threads (only two can concurrently compute, but hundreds can concurrently wait). Take a look at node.js, a recently popular alternative to multi-threaded programming that achieves great throughput for concurrent requests while having only a single thread of execution.
Answer to your 1/2 question:
Though threads run parallel code inside run method of thread is always executed sequentially.
Answer to your 3 question you can best tune your. Application if number of processors = number of threads but this is not a complete truth since if thread is waiting for some blocking operation then it will lead to un optimized performance since during that time another thread could run.
No. You are not synchronizing your threads in any way, so the exact execution order will be at the mercy of the scheduler. Given how your threads are implemented, I don't see how you could ever having "1" (or "A") being printed twice by a single thread.
What caching? And what variables? Your example code has no variables, and therefore nothing that would be appropriate to use with the volatile keyword. It's quite likely that on a given machine running this program will always produce the same result. As noted in #1, you're at the mercy of the scheduler. If the scheduler always behaves the same way, you'll always get the same result. Caching has nothing to do with it.
That depends upon what the threads are doing. If every thread has enough work to load one CPU core to 100%, then yes, having more threads than you have CPU cores is pointless. However, this is very rarely the case. Many threads will spend most of their time sleeping, or waiting for I/O to complete, or otherwise doing things that are not demanding enough to fully load a CPU core. In such a case there's no problem whatsoever with having more threads that CPU cores. In fact, multithreading predates mainstream multicore CPU's, and even back in the days when none of us had more than one CPU core it was still extremely beneficial to be able to have more than one thread.