I am playing around with multithreading and came across an inconsistency when running a small snippet of code. The following code should print out 123123... but what I'm getting is
class RunnableDemo implements Runnable {
private String message;
RunnableDemo(String m) {
message = m;
}
public void run() {
try {
for (int i = 0; i < message.length(); i++) {
System.out.print(message.charAt(i));
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestThread {
public static void main(String args[]) throws InterruptedException {
new Thread(new RunnableDemo("1111111")).start();
new Thread(new RunnableDemo("2222222")).start();
new Thread(new RunnableDemo("3333333")).start();
}
}
Output: 123231231132123231321
Output: 123213123123213213213
Output: 123231213213231231213
What I don't get is that it run correctly the first pass through (prints '123') but then the second pass through it prints '231'. If the thread is printing a char, sleeping 1 second, then repeating. Shouldn't the pattern 123123... be consistent each time I run the code or at least follow the pattern of the first 3 chars?
The following code should print out 123123
Not necessarily. You should basically never rely on threads with no synchronization between them happening to wake up and execute in any particular order.
Let's take the very first character output: there's no guarantee that that will be 1. Yes, you're starting the thread printing 1 first, but that doesn't mean that's the first thread that will actually start executing run first - or even if it does, that doesn't mean that's the first thread that will get as far as the System.out.print call.
Given the fairly long sleep, I would expect (but ideally not rely on) the output being a sequence of 7 "chunks", where each "chunk" consists of the characters "123" in some permutation. But if you've got three threads which all go to sleep for a second at "roughly" the same time, you shouldn't expect them to necessarily wake up in the order 1, 2, 3 - and again, even if they do, one of them may pre-empt another within the loop body.
On a really, really slow machine, even that expectation would be invalid - imagine it takes a random amount of time between 0 and 20 seconds to call charAt - unlikely, but it's a feasible thought experiment. At that point, one of the threads could race ahead and finish its output before another of the threads managed to print anything.
Threads are designed to be independent - if you want them to work in a coordinated fashion, you have to specify that coordination yourself. There are plenty of tools for the job, but don't expect it to happen magically.
You can't predict what piece of program CPU runs at a time. While running some process the CPU converts the process into small pieces of work. As multiple processes are running at a time. CPU has to schedule according to scheduling algorithm implemented. So, in short, you cannot predict what CPU does next unless you programmatically synchronize the pieces of code.
Related
I am currently trying to run multiple methods of the same method at the same time. Right now it is only doing one at a time and then sleeping once it loops through all of them. I need it to do all the values in the array at the same time via the method. Here is my current code:
public static void checkTimer(TS3Api api) {
for (String keys : admins) {
//What I need: Check Groups for all values in string AT THE SAME TIME
checkGroup(api, keys);
}
try {
//Sleep for 10 second
Thread.sleep(10000);
} catch (InterruptedException e) {
// Do nothing
}
}
Thread.sleep(10000) causes the current thread to sleep for 10 seconds. This would be the primary thread. You have not split off any threads from the primary one, so this is working as you wrote it.
Take a look through the Java documentation http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
There are some examples of splitting off threads. This should get you on your way to a solution.
In Java 8 you can write something like:
admins.parallelStream().forEach(keys -> checkGroup(api, keys));
The number of items it will do in parallel are system dependent, however. In any case, it is unlikely you can do all of them in parallel unless your system has at least as many processors as there are items in admins, no matter what approach you take.
I wrote a method that should be repeated 1000 times and the method is again another loop (like a nested loop).Since the running time was not reasonable I decided to write a thread to run it faster. Here is the method:
public class NewClass implements Runnable {
#Override
public void run() {
for (int j = 0; j < 50; j++) {
System.out.println(i+","+j);
/*
*
* my method
*/
}
}
}
and here is the way the main class calls it:
for (int i = 0; i < 1000; i++) {
NewClass myMethod = new NewClass();
Thread thread = new Thread(myMethod);
thread.start();
}
the problem is that when I run it, the thread skips the first iteration (when i=0) in the main class and then in the next iterations, it skips some iterations of inner loop (myMethod). Here is the result of println:
1,0
1,1
2,0
2,1
3,0
3,1
3,2
...
3,22
4,0
...
clearly it skips i=0 and for other iterations it cannot finish it. I'm sure the problem is not in the body of method. I run it several times without thread. It is the first time I write thread and I think the problem is in thread.
Your loop index for i starts from 1 (I'm guessing? It's not even clear why it's in scope), so it's unsurprising that i = 0 does not occur. Similarly, I think you're confused about the printing order, which need not be deterministic. It may be printing the output interspersed with output from other threads. This is normal and expected. I think the code is behaving correctly, it might just not be doing what you want.
I noticed you edited your code. This doesn't really bode well for anybody being able to help you diagnose whatever unexpected behavior you're seeing.
It just so happens that no thread calls the print function while i is zero. You don't compel this ordering, so it may or may not happen in that order. Either of these things can happen.
i is zero
A thread is created.
The thread prints the value of i.
i is incremented.
Or
i is zero
A thread is created.
i is incremented.
The thread prints the value of i.
Your code doesn't enforce either ordering, so it can happen either way. You only have guaranteed ordering between threads when something in your code guarantees such ordering.
clearly it skips i=0 and for other iterations it cannot finish it. I'm sure the problem is not in the body of method. I run it several times without thread. It is the first time I write thread and I think the problem is in thread.
There are 2 reason why this could be happeneing.
You seem to be printing out i which is a shared between threads without any memory synchronization. See the tutorial on memory synchronization. Each processor has internal cached memory so even though i is being modified in the main memory, the processor cache may still see the old value.
You also are probably seeing a race condition. What is happening is that the first two threads (0 and 1) are started before either of their run() methods actually being called. So when they both run and print out 1 because that is what i's value is at the time.
Because of either or both of these reasons, if you run your application 10 times you should see vastly different output.
If you want i to be shared then you could turn it into an AtomicInteger and do something like:
final AtomicInteger i = new AtomicInteger(0);
...
// replacement for your for loop
i.set(0);
while (true) {
if (i.incrementAndGet() >= 1000 {
break;
}
...
}
...
// inside the thread you would print
System.out.println(i + "," + j);
But this mechanism does not solve the race condition. Even better would be to pass in the i value to the NewClass constructor:
private int i;
public NetClass(int i) {
this.i = i;
}
...
Then when you create the instances you do:
NewClass myMethod = new NewClass(i);
I am doing a past exam paper of Java, I am confused about one question listed below:
What would happen when a thread executes the following statement in its run() method? (Choose all that apply.)
sleep(500);
A. It is going to stop execution, and start executing exactly 500 milliseconds later.
B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.
C. It is going to result in a compiler error because you cannot call the sleep(…) method inside the run() method.
D. It is going to result in a compiler error because the sleep(…) method does not take any argument.
I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me? Many thanks.
I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me?
Yes, depending on your application, you certainly might get 500ms of sleep time and not a nanosecond more.
However, the reason why B is the better answer is that there are no guarantees about when any thread will be run again. You could have an application with a large number of CPU bound threads. Even though the slept thread is now able to be run, it might not get any cycles for a significant period of time. The precise sleep time also depends highly on the particulars of the OS thread scheduler and clock accuracy. Your application also may also have to compete with other applications on the same system which may delay its continued execution.
For example, this following program on my extremely fast 8xi7 CPU Macbook Pro shows a max-sleep of 604ms:
public class MaxSleep {
public static void main(String[] args) throws Exception {
final AtomicLong maxSleep = new AtomicLong(0);
ExecutorService threadPool = Executors.newCachedThreadPool();
// fork 1000 threads
for (int i = 0; i < 1000; i++) {
threadPool.submit(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
long total = 0;
// spin doing something that eats CPU
for (int j = 0; j < 10000000; j++) {
total += j;
}
// this IO is the real time sink though
System.out.println("total = " + total);
try {
long before = System.currentTimeMillis();
Thread.sleep(500);
long diff = System.currentTimeMillis() - before;
// update the max value
while (true) {
long max = maxSleep.get();
if (diff <= max) {
break;
}
if (maxSleep.compareAndSet(max, diff)) {
break;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
System.out.println("max sleep ms = " + maxSleep);
}
}
JVM cannot guarantee exactly 500 ms but it will start on or after ~500 ms as it will need to start its 'engine' back considering no other threads are blocking any resources which may delay a bit.
Read: Inside the Hotspot VM: Clocks, Timers and Scheduling Events
Edit: As Gray pointed out in the comment - the scheduling with other threads also a factor, swapping from one to another may cost some time.
According to Javadoc:-
Sleep()
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors.
So it may be ~500ms
B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.
Looks more prominent.
As you know that there are two very closely-related states in Thread : Running and Runnable.
Running : means currently executing thread. Its execution is currently going on.
Runnable : means thread is ready to get processed or executed. But is waiting to be picked up by Thread Schedular. Now this thread schedular, as per its own wish/defined algorithm depending upon the JVM(for example, slicing algorithm) will pick up one of the available/Runnable threads to process them.
So whenever you call sleep method, it only guarantees that the execution of the code by the thread which it ran on, is paused for the specified milliseconds in the argument(e.g. 300ms in threadRef.sleep(300);). As soon as the time defined goes by, it comes back to Runnable state(means back to Available State to be picked up by Thread Schedular).
Therefore, there is no guarantee that your remaining code will start getting executed immediately after sleep method completion.
These sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS. Option B: Not earlier than 500 is more correct.
You cannot select A and B as they are opposite to each other, the main difference: exactly 500 milliseconds later and not earlier than 500 milliseconds later
first mean exactly what it means (500 milliseconds only), second means that it can sleep 501 or 502 or even 50000000000000
next question - why B is true, it is not so simply question, you need to understand what is the different between hard-realtime and soft-realtime, and explaining of all reasons is quite offtopic, so simply answer - because of many technical reasons java cannot guarantee hard real time execution of your code, this is why it stated that sleep will finish not earlier than ...
you can read about thread scheduling, priorities, garbage collection, preemptive multitasking - all these are related to this
I'm making a game in Java using Netbeans() and I want a Boolean variable takes the value of true when it is taken an item "X", the item "X" represents a character's ability which lasts "N" miliSeconds, what is the best way to do that after "N" miliSeconds the variable returns the value from false?
Now, not sure if it is my place to say, but I have a recommendation and an answer.
I would recommend building a skills/ability library. Use that to track cool downs, casting times etc. It would be more efficient overall.
As for the answer, check to see if the current time minus the time the ability was started is over 1000, then set the variable. Have this be used in a looped system such as a thread.
new Thread(new Runnable() {
try {
Thread.sleep(1000); //1 second
catch (InterruptedException annoyingCheckedException) {}
x = "foo";
}
You can start a new thread which waits a second (or however long you want it to wait) and then changes x.
The try-catch is because when sleeping, Java forces you to catch an InterruptedException which will be thrown if the thread is interrupted. In this case, you are never going to interrupt the thread so you don't need to worry about it.
I am using BlockingQueue:s (trying both ArrayBlockingQueue and LinkedBlockingQueue) to pass objects between different threads in an application I’m currently working on. Performance and latency is relatively important in this application, so I was curious how much time it takes to pass objects between two threads using a BlockingQueue. In order to measure this, I wrote a simple program with two threads (one consumer and one producer), where I let the producer pass a timestamp (taken using System.nanoTime()) to the consumer, see code below.
I recall reading somewhere on some forum that it took about 10 microseconds for someone else who tried this (don’t know on what OS and hardware that was on), so I was not too surprised when it took ~30 microseconds for me on my windows 7 box (Intel E7500 core 2 duo CPU, 2.93GHz), whilst running a lot of other applications in the background. However, I was quite surprised when I did the same test on our much faster Linux server (two Intel X5677 3.46GHz quad-core CPUs, running Debian 5 with kernel 2.6.26-2-amd64). I expected the latency to be lower than on my windows box , but on the contrary it was much higher - ~75 – 100 microseconds! Both tests were done with Sun’s Hotspot JVM version 1.6.0-23.
Has anyone else done any similar tests with similar results on Linux? Or does anyone know why it is so much slower on Linux (with better hardware), could it be that thread switching simply is this much slower on Linux compared to windows? If that’s the case, it’s seems like windows is actually much better suited for some kind of applications. Any help in helping me understanding the relatively high figures are much appreciated.
Edit:
After a comment from DaveC, I also did a test where I restricted the JVM (on the Linux machine) to a single core (i.e. all threads running on the same core). This changed the results dramatically - the latency went down to below 20 microseconds, i.e. better than the results on the Windows machine. I also did some tests where I restricted the producer thread to one core and the consumer thread to another (trying both to have them on the same socket and on different sockets), but this did not seem to help - the latency was still ~75 microseconds. Btw, this test application is pretty much all I'm running on the machine while performering test.
Does anyone know if these results make sense? Should it really be that much slower if the producer and the consumer are running on different cores? Any input is really appreciated.
Edited again (6 January):
I experimented with different changes to the code and running environment:
I upgraded the Linux kernel to 2.6.36.2 (from 2.6.26.2). After the kernel upgrade, the measured time changed to 60 microseconds with very small variations, from 75-100 before the upgrade. Setting CPU affinity for the producer and consumer threads had no effect, except when restricting them to the same core. When running on the same core, the latency measured was 13 microseconds.
In the original code, I had the producer go to sleep for 1 second between every iteration, in order to give the consumer enough time to calculate the elapsed time and print it to the console. If I remove the call to Thread.sleep () and instead let both the producer and consumer call barrier.await() in every iteration (the consumer calls it after having printed the elapsed time to the console), the measured latency is reduced from 60 microseconds to below 10 microseconds. If running the threads on the same core, the latency gets below 1 microsecond. Can anyone explain why this reduced the latency so significantly? My first guess was that the change had the effect that the producer called queue.put() before the consumer called queue.take(), so the consumer never had to block, but after playing around with a modified version of ArrayBlockingQueue, I found this guess to be false – the consumer did in fact block. If you have some other guess, please let me know. (Btw, if I let the producer call both Thread.sleep() and barrier.await(), the latency remains at 60 microseconds).
I also tried another approach – instead of calling queue.take(), I called queue.poll() with a timeout of 100 micros. This reduced the average latency to below 10 microseconds, but is of course much more CPU intensive (but probably less CPU intensive that busy waiting?).
Edited again (10 January) - Problem solved:
ninjalj suggested that the latency of ~60 microseconds was due to the CPU having to wake up from deeper sleep states - and he was completely right! After disabling C-states in BIOS, the latency was reduced to <10 microseconds. This explains why I got so much better latency under point 2 above - when I sent objects more frequently the CPU was kept busy enough not to go to the deeper sleep states. Many thanks to everyone who has taken time to read my question and shared your thoughts here!
...
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CyclicBarrier;
public class QueueTest {
ArrayBlockingQueue<Long> queue = new ArrayBlockingQueue<Long>(10);
Thread consumerThread;
CyclicBarrier barrier = new CyclicBarrier(2);
static final int RUNS = 500000;
volatile int sleep = 1000;
public void start() {
consumerThread = new Thread(new Runnable() {
#Override
public void run() {
try {
barrier.await();
for(int i = 0; i < RUNS; i++) {
consume();
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
consumerThread.start();
try {
barrier.await();
} catch (Exception e) { e.printStackTrace(); }
for(int i = 0; i < RUNS; i++) {
try {
if(sleep > 0)
Thread.sleep(sleep);
produce();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void produce() {
try {
queue.put(System.nanoTime());
} catch (InterruptedException e) {
}
}
public void consume() {
try {
long t = queue.take();
long now = System.nanoTime();
long time = (now - t) / 1000; // Divide by 1000 to get result in microseconds
if(sleep > 0) {
System.out.println("Time: " + time);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
QueueTest test = new QueueTest();
System.out.println("Starting...");
// Run first once, ignoring results
test.sleep = 0;
test.start();
// Run again, printing the results
System.out.println("Starting again...");
test.sleep = 1000;
test.start();
}
}
Your test is not a good measure of queue handoff latency because you have a single thread reading off the queue which writes synchronously to System.out (doing a String and long concatenation while it is at it) before it takes again. To measure this properly you need to move this activity out of this thread and do as little work as possible in the taking thread.
You'd be better off just doing the calculation (then-now) in the taker and adding the result to some other collection which is periodically drained by another thread that outputs the results. I tend to do this by adding to an appropriately presized array backed structure accessed via an AtomicReference (hence the reporting thread just has to getAndSet on that reference with another instance of that storage structure in order to grab the latest batch of results; e.g. make 2 lists, set one as active, every x s a thread wakes up and swaps the active and the passive ones). You can then report some distribution instead of every single result (e.g. a decile range) which means you don't generate vast log files with every run and get useful information printed for you.
FWIW I concur with the times Peter Lawrey stated & if latency is really critical then you need to think about busy waiting with appropriate cpu affinity (i.e. dedicate a core to that thread)
EDIT after Jan 6
If I remove the call to Thread.sleep () and instead let both the producer and consumer call barrier.await() in every iteration (the consumer calls it after having printed the elapsed time to the console), the measured latency is reduced from 60 microseconds to below 10 microseconds. If running the threads on the same core, the latency gets below 1 microsecond. Can anyone explain why this reduced the latency so significantly?
You're looking at the difference between java.util.concurrent.locks.LockSupport#park (and corresponding unpark) and Thread#sleep. Most j.u.c. stuff is built on LockSupport (often via an AbstractQueuedSynchronizer that ReentrantLock provides or directly) and this (in Hotspot) resolves down to sun.misc.Unsafe#park (and unpark) and this tends to end up in the hands of the pthread (posix threads) lib. Typically pthread_cond_broadcast to wake up and pthread_cond_wait or pthread_cond_timedwait for things like BlockingQueue#take.
I can't say I've ever looked at how Thread#sleep is actually implemented (cos I've never come across something low latency that isn't a condition based wait) but I would imagine that it causes it to be demoted by the schedular in a more aggressive way than the pthread signalling mechanism and that is what accounts for the latency difference.
I would use just an ArrayBlockingQueue if you can. When I have used it the latency was between 8-18 microseconds on Linux. Some point of note.
The cost is largely the time it takes to wake up the thread. When you wake up a thread its data/code won't be in cache so you will find that if you time what happens after a thread has woken that can take 2-5x longer than if you were to run the same thing repeatedly.
Certain operations use OS calls (such as locking/cyclic barriers) these are often more expensive in a low latency scenario than busy waiting. I suggest trying to busy wait your producer rather than use a CyclicBarrier. You could busy wait your consumer as well but this could be unreasonably expensive on a real system.
#Peter Lawrey
Certain operations use OS calls (such as locking/cyclic barriers)
Those are NOT OS (kernel) calls. Implemented via simple CAS (which on x86 comes w/ free memory fence as well)
One more: dont use ArrayBlockingQueue unless you know why (you use it).
#OP:
Look at ThreadPoolExecutor, it offers excellent producer/consumer framework.
Edit below:
to reduce the latency (baring the busy wait), change the queue to SynchronousQueue add the following like before starting the consumer
...
consumerThread.setPriority(Thread.MAX_PRIORITY);
consumerThread.start();
This is the best you can get.
Edit2:
Here w/ sync. queue. And not printing the results.
package t1;
import java.math.BigDecimal;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.SynchronousQueue;
public class QueueTest {
static final int RUNS = 250000;
final SynchronousQueue<Long> queue = new SynchronousQueue<Long>();
int sleep = 1000;
long[] results = new long[0];
public void start(final int runs) throws Exception {
results = new long[runs];
final CountDownLatch barrier = new CountDownLatch(1);
Thread consumerThread = new Thread(new Runnable() {
#Override
public void run() {
barrier.countDown();
try {
for(int i = 0; i < runs; i++) {
results[i] = consume();
}
} catch (Exception e) {
return;
}
}
});
consumerThread.setPriority(Thread.MAX_PRIORITY);
consumerThread.start();
barrier.await();
final long sleep = this.sleep;
for(int i = 0; i < runs; i++) {
try {
doProduce(sleep);
} catch (Exception e) {
return;
}
}
}
private void doProduce(final long sleep) throws InterruptedException {
produce();
}
public void produce() throws InterruptedException {
queue.put(new Long(System.nanoTime()));//new Long() is faster than value of
}
public long consume() throws InterruptedException {
long t = queue.take();
long now = System.nanoTime();
return now-t;
}
public static void main(String[] args) throws Throwable {
QueueTest test = new QueueTest();
System.out.println("Starting + warming up...");
// Run first once, ignoring results
test.sleep = 0;
test.start(15000);//10k is the normal warm-up for -server hotspot
// Run again, printing the results
System.gc();
System.out.println("Starting again...");
test.sleep = 1000;//ignored now
Thread.yield();
test.start(RUNS);
long sum = 0;
for (long elapsed: test.results){
sum+=elapsed;
}
BigDecimal elapsed = BigDecimal.valueOf(sum, 3).divide(BigDecimal.valueOf(test.results.length), BigDecimal.ROUND_HALF_UP);
System.out.printf("Avg: %1.3f micros%n", elapsed);
}
}
If latency is critical and you do not require strict FIFO semantics, then you may want to consider JSR-166's LinkedTransferQueue. It enables elimination so that opposing operations can exchange values instead of synchronizing on the queue data structure. This approach helps reduce contention, enables parallel exchanges, and avoids thread sleep/wake-up penalties.