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);
Related
When it comes to counting, should a do-while loop be used, or a for loop? Because this:
class Main {
public static void main(String[] args) {
int times = 1;
do {
System.out.println("I have printed " + times + " times.");
times++;
} while (times < 6);
}
}
Seems to do the exact same thing as this:
class Main {
public static void main(String[] args) {
for (int times = 1; times < 6; times++) {
System.out.println("I have printed " + times + " times.");
}
}
}
Is it a difference in speed? Preference? Situation? Personal quirks? Some kind of "Java social taboo"? I have no idea. Either seem to be able to be used for effective counting, just that one takes a lot more. And both print the exact same thing.
System.out.println("Many thanks!!");
You're right, these do the same thing (except one starts counting at 0 and the other at 1, but that's just an implementation detail). If your program knows in advance (before the loop starts) how many times you want the loop to iterate, most Java developers will tell you to go with a for loop. That's what it's designed for.
A while loop or do while loop is better suited for situations where you're looking for a specific value or condition before you exit the loop. (Something like count >= 10 or userInput.equals("N"). Anything that evaluates to a boolean True/False value.)
When faced with these kind of dilemmas, aim for readability and familiarity. You should not concern yourself with micro-optimizations. Focus on readability and clearly conveying you intent. Do as other do in similar situation.
Like #Bill-The-Lizard said, while loop suggests to the reader of your code that you opted for it, because you're not counting, but repeating until a condition is met. At least once - otherwise you'd have chosen while(...){ } loop.
In other words, for, do {} while() and while() { } generally work the same. But one may better convey you intent in your particular piece of logic.
I think it's more of a readability and syntactic sugar. This while condition
while (condition)
can also be written as
for (; condition; )
but obviously the first one looks lot better and is more readable.
It depends on the programmer's choice when to use for loop or do while loop but the general practice followed by most of the programmers is
For loop
When you know that the loop will execute a predefined number of times(general practice since you can also use for(;true;) which loops forever).
For example a loop which runs 10 times or n number of times where n is a variable
for(int i = 0; i < n; i++) {
//Do something
}
While loop
When you know that the loop should terminate after the evaluation of a specific condition as true or else you want the loop to run forever (like while(true)) and check the break conditions inside the while loop.
Also the while loop is preferred when you can't figure out the conditions in the first place and start with while(true) but once you write code inside the loop you get good understanding of what's happening and get the idea about which conditions to check thus when to exit the loop.
For example
while(x != 0) {
//Do something;
x--;
}
while(true) {
// some code to execute on which the condition depends
if(condition is true) {
break;
}
}
Do while loop
Do while loop is similar to the while loop but with a small difference. That is it allows the first iteration to happen without checking the condition(specified in the while statement, but you can still evaluate the condition inside the block(curly braces)).
By convention most Java developers use for loops. Effective Java recommends for loops instead of while loops because the loop variable can use a tighter scope which reduces bugs. http://www.corejavaguru.com/effective-java/items/45
Recent versions of Java also allow the following
IntStream.range(0, 6).forEach(
i -> System.out.println("I have printed " + i + " times.")
);
Beyond personal preferences, this one has the advantage that the index is maintained by the runtime and there is no need for the programmer to ++i
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.
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
When executing a while loop, does java constantly check if the parameter(s) are true? For example if a while loop is
while(k=7) {
Thread.sleep(5000);
}
but during the 5 seconds another thread changes k to 8, would the loop continue waiting or exit immediately?
No, it will only check when the execution path takes it there. Thus, it will check every 5 seconds in your example.
If you wanted to be notified immediately, you would have to use wait(), notify(), or some other synchronization method.
Here is an example
No. Even if k were volatile (or, worse, changed from another thread without you making it volatile; bad idea) or an object whose properties could change via the methods called inside the loop, it will only be checked at the end of the loop body, deciding to repeat the body or continue past the loop.
You can break out of the loop by interrupting the thread and having the catch outside the loop, or with an internal check and break.
The condition is checked once at the start and, if the loop is entered, once after the execution of the body on each iteration. So no, it will not exit immediately, even if k is altered while the body is being executed.
Oh, and you probably meant k == 7 (recall that == compares while = assigns). Some will even write 7 == k to avoid potentially making this mistake.
This doesn't really have much to do with threads. For instance, consider:
int k = 7;
while (k == 7) {
k = 8;
System.out.println("here!");
}
here!
Notice how the body is still fully executed even though k is immediately changed to a value that no longer satisfies the loop condition.
I was given a question in class saying 'What are the possible final values of a? (Assume that each statement is a unit of execution. You do not need to consider the problem at the instruction level.)'. With additional information:
Thread A: a = 3 (A1) and a = a + 1 (A2)
Thread B: a = 5 (B1) and a = a + 7 (B2)
So after some thought that First thread output should be 4 and second threads output should be 12.
So I did the test script to see if that's correct and output shows what I expected Thread A: 4 and Thread B: 12.
The question is, should I expect other values? Or maybe I'm just implementing this question wrong? How I can tweak this code to get other values, if possible? Is that a tricky question, or its just me?
EDIT: Since code was not really needed for my homework assignment, lets focus on theoretical implementation of such problem.
Assuming you do fix your code to correctly implement threading, given today's CPU speeds and the overhead of starting threads/scheduling I bet you won't see any concurrency bugs, because either the first thread or the second one will finish their update of a before the other one has a chance to start, so you'll probably always get 4 and 12 as results.
You'll need much more lengthy tasks for a data-race to occur.
If you ever correct this so it really exhibits threading rather than sequential execution, the correct answer would be that in the absence of any kind of synchronization the behaviour is undefined.
Your calls to FirstThread and SecondThread are running on the main thread, not threadA or threadB. Also, the run() method does nothing.
Any references to threading in this problem are merely misdirection (noise) and have nothing to do with the output.
(Also the method names FirstThread and SecondThread should start with a lowercase letter to match Java convention)
If I understand your question correctly, the code you give was not given as part of the homework question but rather represents you attempt to answer it. Given that, as Tudor already points out even in a correct implementation you might not see any "surprising" values, even if you run the program a few hundred times. Concurrency bugs are hard to find by testing.
My hint for understanding the correct answer is the following:
Consider you are cooking two dishes for dinner with your loved one. You can cook the (spicy) main dish first and the (sweet) desert afterwards. (No threading). Or you cook them at the same time, switching between the two recipes. Both of them might refer to a pan (initially filled with air), one tells you to replace the content of your pan with eggs, the other to replace the content with oil and then add spices. Because you are a bad cook (you didn't learn about synchronization yet) you start by putting in oil, then replace everything in it by eggs, add sugar and then return to the first recipe and add spices ... what will it taste like?
You can get other values but you need to do something to make the program do because something with thread is random and it's hard to control.you can try my code i think there's something wrong in your code, but i don't change it, ok?
public class Threads implements Runnable
{
int a = 0;
public void run() { }
public int FirstThread()
{
a = 3;
Thread.sleep(2000);
a = a + 1;
return a;
}
public int SecondThread()
{
a = 5;
a = a + 7;
return a;
}
}
or use this one
public class Threads implements Runnable
{
int a = 0;
public void run() { }
public int FirstThread()
{
a = 3;
a = a + 1;
return a;
}
public int SecondThread()
{
a = 5;
Thread.sleep(2000);
a = a + 7;
return a;
}
}
just try it!!!