Recently I've seen some code which depends on order of execution in different threads which was achieved by calling Thread.sleep with some values. It worked without any problems but I'm sure that in some rare cases it would not. I wrote some code where order of output depends on how precisely Thread.sleep works.
public class Test {
public static Thread createDelayedPrintThread(final String text,
final long delay) {
return new Thread() {
public void run() {
try {
Thread.sleep(delay);
System.out.print(text);
} catch (InterruptedException e) {
}
}
};
}
public static void main(String[] args) {
Thread t1 = createDelayedPrintThread("t1", 10);
Thread t2 = createDelayedPrintThread("t2", 10);
t1.start();
t2.start();
}
}
This code obliviously can output booth t1t2 and t2t1 so I made delays different:
Thread t1 = createDelayedPrintThread("t1", 10);
Thread t2 = createDelayedPrintThread("t2", 20);
Now it outputs t1t2 but I still sometimes get t2t1. It usually happens when I do some CPU/IO intensive operations.
If I change delays to extremely big values
Thread t1 = createDelayedPrintThread("t1", 1_000); // one second
Thread t2 = createDelayedPrintThread("t2", 60_000); // one minute
would be there any guarantees that the application will output t1t2?
First, your understanding is correct; no amount of Thread.sleep() (and by the way, since Java 5 you should really be using TimeUnit instead, as in TimeUnit.SECONDS.sleep(2L)) will guarantee in-order execution; you cannot guarantee when the OS will schedule this or that thread.
would be there any guarantees that the application will output t1t2?
Yes.
For instance, a volatile boolean variable shared by those two threads will do (although you'll need to busy wait so this is not ideal). Another example is a Semaphore.
Solutions are many, and what you will end up with depends entirely upon your requirements.
Thread.sleep is not guarantees.
Java tutorial, about Thread.sleep():
"However, these sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS. Also, the sleep period can be terminated by interrupts, as we'll see in a later section. In any case, you cannot assume that invoking sleep will suspend the thread for precisely the time period specified."
So, you need add other multithreading logic for guarantees execution order.
Related
I have a spin-wait loop that is busy-waiting for a flag to be set. However, it can take a lot of time for that to happen - minutes, or even hours.
Would Thread.sleep() be more efficient than Thread.onSpinWait()?
From the documentation of Thread#onSpinWait:
The runtime may take action to improve the performance of invoking spin-wait loop constructions.
Thread#sleep does not do this, but rather releases the processor to another runnable thread until its sleep time has elapsed.
If I were you, I would redesign your system to use interrupts (events) rather than polling (busy waiting), as that would result in a better performance boost than either Thread#sleep or Thread#onSpinWait.
So you wanted to see a short example about Object and its long-available wait() and notify/All() methods? (They are already there in JLS 1.0, from 20+ years ago)
Say no more:
public class NotifyTest {
private boolean flag = false;
public synchronized boolean getFlag() {
return flag;
}
public synchronized void setFlag(boolean newFlag) {
flag = newFlag;
notifyAll();
}
public static void main(String[] args) throws Exception {
final NotifyTest test = new NotifyTest();
new Thread(new Runnable() {
#Override
public void run() {
System.out.printf("I am thread at %,d, flag is %b\n",
System.currentTimeMillis(), test.getFlag());
synchronized (test) {
try {
test.wait();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
System.out.printf("I am thread at %,d, flag is %b\n",
System.currentTimeMillis(), test.getFlag());
}
}).start();
System.out.printf("I am main at %,d, flag is %b\n",
System.currentTimeMillis(), test.getFlag());
Thread.sleep(2000);
test.setFlag(true);
System.out.printf("I am main at %,d, flag is %b\n",
System.currentTimeMillis(), test.getFlag());
}
}
If your wait loop has anything else to do, Object.wait() has variants with timeout too.
So objects can be wait()-ed on and then waiting threads can be notified (one of the waiters via notify() or all of them via notifyAll()), and they do not even have to know about each other.
As both waiting and notifying has to happen inside a synchronized block, it is safe and possible to start the block, check the variable/flag/anything, and issue the wait conditionally (just these constructs are not shown here).
Neither sleep nor a spin lock is what you want in this situation. sleep is the wrong choice because you don't know how long you're going to need to sleep beforehand. Doing some sort of spin lock loop is wrong because spin locks are busy waits and thus consume CPU cycles and are only really meant for very short waits in anticipation of a resource becoming available very quickly. What you want to do here is set up a semaphore. Have thread 1 wait for the semaphore to be set by thread 2.
Since order of execution is not guaranteed. In below program order of execution for main method can be like below ?
t2.start();
t2.join();
t1.start();
t1.join();
Program is:
public class Puzzle {
static boolean answerReady = false;
static int answer = 0;
static Thread t1 =
new Thread() {
public void run() {
answer = 42;
answerReady = true;
}
};
static Thread t2 =
new Thread() {
public void run() {
while (!answerReady) Thread.sleep(100);
System.out.println("The meaning of life is: " + answer);
}
};
public static void main(String[] args) throws InterruptedException {
t1.start();
t2.start();
t1.join();
t2.join();
}
}
Edit: want to add few things after seeing comments
answerReady may never become true. Agree.
what are special conditions when order of execution can be changed ?
why main method is correctly synchronized here ?
The Java Language Specification dictates what conforming JVMs may do or not. See
§17.4.5. Happens-before Order
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.
If we have two actions x and y, we write hb(x, y) to indicate that x happens-before y.
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
…
Since your invocations of start() and join() are actions of the same thread, they are ordered in respect to the program order.
I think, it should be obvious that if that simple guaranty didn’t exist, even single threaded programming was impossible.
This does not imply the absence of reordering in the code. It only implies that such optimizations must happen in a way that retains the observable behavior of these actions when executing this code.
The point here is, that while the main thread will consistently do what you told it to do, other threads not having a happens-before relationship to either of these actions, might not see the actions in the same way. In your case, with the three threads shown, there are several relationships:
continuation of §17.4.5
…
If hb(x, y) and hb(y, z), then hb(x, z).
…
A call to start() on a thread happens-before any actions in the started thread.
All actions in a thread happen-before any other thread successfully returns from a join() on that thread.
From this you can derive that all three threads of your code agree on what the main thread is doing in most parts.
Of course, this doesn’t change the fact that the two spawned threads are improperly (not at all) synchronized and t2 may print the value 0 instead of 42 or never terminate at all.
No. the order of execution on the main thread is as you've declared it in main:
t1.start();
t2.start();
t1.join();
t2.join();
The only thing that's not guaraneed is the content of the threads t1 and t2.
I would like to understand that does java actually run multiple threads in parallel in a multi core CPU, or there is context switching between threads and only one thread is active and others are waiting for their turn to run.
In other words, is there a possibility that 2 threads are running in parallel???
Because my Thread.currentThread() does not give me a array of threads, but only one thread which is running.
So what is the truth, does only one thread run at a time while others wait or multiple threads can run in parallel, if yes , then why my Thread.currentThread() method return only 1 thread object.
Edit : .....
I have created 2 classes to count numbers
1 class does it synchronously and the other one divides it into two halves and executes the two halves in 2 threads..(intel i5(4 CPUs), 8GB ram)
the code is as follows :
common class :
class Answer{
long ans = 0L;}
Multi Thread execution :
public class Sheet2 {
public static void main(String[] args) {
final Answer ans1 = new Answer();
final Answer ans2 = new Answer();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for(int i=0;i<=500000; i++) {
ans1.ans = ans1.ans + i;
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for(int i=500001;i<=1000000; i++) {
ans2.ans = ans2.ans + i;
}
}
});
long l1 = System.currentTimeMillis();
try {
t1.start();t2.start();
t1.join();
t2.join();
long l2 = System.currentTimeMillis();
System.out.println("ans :" + (ans1.ans + ans2.ans) +" in "+(l2-l1) +" milliseconds");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Single Thread execution :
public class Sheet3 {
public static void main(String[] args) {
final Answer ans1 = new Answer();
long l1 = System.currentTimeMillis();
for(int i=0;i<=1000000; i++) {
ans1.ans = ans1.ans + i;
}
long l2 = System.currentTimeMillis();
System.out.println("ans :" + (ans1.ans ) +" in "+(l2-l1) +" milliseconds"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
My Single thread execution is faster than my multi threaded execution, I though the context switching was putting a overhead on the execution initially and hence the multithreaded execution output was slower, now I am having muti core CPU (4 CPU), but still single threaded execution is faster in this example..
Can you please explain the scenario here... is it because my other processes are eating up the other cores and hence my threads are not running in parallel and performing time slicing on the CPU ???
Kindly throw some light on this topic.
Thanks in advance.
Cheers.!!!
In short yes it does run on separate threads. You can test it by creating 100 threads and checking in your process explorer it will say 100 threads. Also you can do some computation in each thread and you will see your multicore processor go upto 100% usage.
Thread.currentThread gives you the current thread you are running from.
When you start your program you are running on the "main" thread.
As soon as you start a new thread
new Thread(myRunnable);
any code located in the myRunnable will run on the new thread while your current thread is is still on the main Thread.
If you check out the API http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html it gives allot more detailed description of the thread.
The actual threading mechanism can vary between CPU architectures. But the real problem is that you're misinterpreting the method name. Thread.currentThread() doesn't return the thread executing at the current moment in time; it returns the thread currently executing the method call, that is, itself.
Yes it does. Run any simple infinite loop on more than one threads and you'll see the cpu usage > 100% on a multi-core CPU.
Yes it does run threads concurrently .That is the very purpose of the multithreading concept .you may find the folowing discussion helpful :
Current Thread Method java
Not a complete answer here, just adding to what others already have said:
The Java Language Specification does not require that threads run in parallel, but it allows them to do so. What actually happens in any given Java Virtual Machine depends on how that JVM is implemented.
Any practical JVM will create one "native" (i.e., operating system) thread for each Java thread, and let the operating system take care of scheduling, locking, waiting, notifying,...
I'm trying to learn about threads and I do not understand the join() method.
I have a Thread (ThreadAdd.java) which adds 1 to a static int.
public class ThreadAdd extends Thread{
public static int count;
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ThreadAdd.class.getName()).log(Level.SEVERE, null, ex);
}
ThreadAdd.count++;
}
}
In my main method I launch 2 threads :
public static void main(String[] args) throws InterruptedException {
ThreadAdd s1 = new ThreadAdd();
ThreadAdd s2 = new ThreadAdd();
s1.start();s2.start();
s1.join();
s2.join();
System.out.println(ThreadAdd.count);
}
I do not understand why most of the time the result is 2 but sometimes it returns 1.
The reason why you sometimes see 1 is not because join() fails to wait for the thread to finish, but because both threads tried to modify the value concurrently. When this happens, you may see unexpected results: for example, when both threads try to increment count which is zero, they both could read zero, then add 1 to it, and store the result. Both of them will store the same exact result, i.e. 1, so that's what you are going to see no matter how long you wait.
To fix this problem, add synchronized around the increment, or use AtomicInteger:
public static AtomicInteger count = new AtomicInteger(0);
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(ThreadAdd.class.getName()).log(Level.SEVERE, null, ex);
}
ThreadAdd.count.incrementAndGet();
}
The join method is not the real issue here. The problem is that your counter is not prepared for interthread synchronization, which may lead to each thread observing a different value in count.
It is highly recommended that you study some topics of concurrent programming, including how it is handled in Java.
Because you're not synchronizing the increment of the integer count. The two threads may interleave while incrementing the variable.
See http://docs.oracle.com/javase/tutorial/essential/concurrency/interfere.html for an explanation. The example in the link is similar to your example and a solution provided to avoid this thread interference is to use atomic variables like java.util.concurrent.atomic.AtomicInteger.
Your count variable isn't volatile, and so there's no requirement for threads to check its value each time, and occasionally instruction ordering will cause errors like that.
In fact, though, since count++ is syntactic sugar for count = count + 1, even making the variable volatile won't ensure that you don't have the problem, since there's a race condition between the read and the subsequent write.
To make code like this safe, use an AtomicInteger instead.
This has nothing to do with the join. The thread that waits by using join() is your main thread. The two other threads are not waiting for anything. And the join is not causing them to do anything differently.
And as the other answers said, the two threads are concurrently writing to the same variable, and therefore you get the result you see.
Perhaps you were expecting the join() to delay one of the threads so that it doesn't work concurrently with the other, but that's not how it works. The only thread that is delayed is the caller of join(), not the target thread.
There's something odd about the implementation of the BoundedExecutor in the book Java Concurrency in Practice.
It's supposed to throttle task submission to the Executor by blocking the submitting thread when there are enough threads either queued or running in the Executor.
This is the implementation (after adding the missing rethrow in the catch clause):
public class BoundedExecutor {
private final Executor exec;
private final Semaphore semaphore;
public BoundedExecutor(Executor exec, int bound) {
this.exec = exec;
this.semaphore = new Semaphore(bound);
}
public void submitTask(final Runnable command) throws InterruptedException, RejectedExecutionException {
semaphore.acquire();
try {
exec.execute(new Runnable() {
#Override public void run() {
try {
command.run();
} finally {
semaphore.release();
}
}
});
} catch (RejectedExecutionException e) {
semaphore.release();
throw e;
}
}
When I instantiate the BoundedExecutor with an Executors.newCachedThreadPool() and a bound of 4, I would expect the number of threads instantiated by the cached thread pool to never exceed 4. In practice, however, it does. I've gotten this little test program to create as much as 11 threads:
public static void main(String[] args) throws Exception {
class CountingThreadFactory implements ThreadFactory {
int count;
#Override public Thread newThread(Runnable r) {
++count;
return new Thread(r);
}
}
List<Integer> counts = new ArrayList<Integer>();
for (int n = 0; n < 100; ++n) {
CountingThreadFactory countingThreadFactory = new CountingThreadFactory();
ExecutorService exec = Executors.newCachedThreadPool(countingThreadFactory);
try {
BoundedExecutor be = new BoundedExecutor(exec, 4);
for (int i = 0; i < 20000; ++i) {
be.submitTask(new Runnable() {
#Override public void run() {}
});
}
} finally {
exec.shutdown();
}
counts.add(countingThreadFactory.count);
}
System.out.println(Collections.max(counts));
}
I think there's a tiny little time frame between the release of the semaphore and the task ending, where another thread can aquire a permit and submit a task while the releasing thread hasn't finished yet. In other words, it has a race condition.
Can someone confirm this?
BoundedExecutor was indeed intended as an illustration of how to throttle task submission, not as a way to place a bound on thread pool size. There are more direct ways to achieve the latter, as at least one comment pointed out.
But the other answers don't mention the text in the book that says to use an unbounded queue and to
set the bound on the semaphore to be equal to the pool size plus the
number of queued tasks you want to allow, since the semaphore is
bounding the number of tasks both currently executing and awaiting
execution. [JCiP, end of section 8.3.3]
By mentioning unbounded queues and pool size, we were implying (apparently not very clearly) the use of a thread pool of bounded size.
What has always bothered me about BoundedExecutor, however, is that it doesn't implement the ExecutorService interface. A modern way to achieve similar functionality and still implement the standard interfaces would be to use Guava's listeningDecorator method and ForwardingListeningExecutorService class.
You are correct in your analysis of the race condition. There is no synchronization guarantees between the ExecutorService & the Semaphore.
However, I do not know if throttling the number of threads is what the BoundedExecutor is used for. I think it is more for throttling the number of tasks submitted to the service. Imagine if you have 5 million tasks that need to submit, and if you submit more then 10,000 of them you run out of memory.
Well you only will ever have 4 threads running at any given time, why would you want to try and queue up all 5 millions tasks? You can use a construct similar to this to throttle the number of tasks queued up at any given time. What you should get out of this is that at any given time there are only 4 tasks running.
Obviously the resolution to this is to use a Executors.newFixedThreadPool(4).
I see as much as 9 threads created at once. I suspect there is a race condition which causes there to be more thread than required.
This could be because there is before and after running the task work to be done. This means that even though there is only 4 thread inside your block of code, there is a number of thread stopping a previous task or getting ready to start a new task.
i.e. the thread does a release() while it is still running. Even though its the last thing you do its not the last thing it does before acquiring a new task.