java thread start method or method - java

This code came from sample OCP/SCJP
I'm not really sure why Printx() is called before run().
and why this is guaranteed?
public class ConstructorOrRun extends Thread {
private int x = 2;
public ConstructorOrRun() throws Exception {
x = 5;
start();
}
public void printX() throws Exception {
x = x - 1;
System.out.print(x);
}
public void run() {
x *= 2;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
new ConstructorOrRun().printX();
}
}

I don't think 'guaranteed' is the right word here. In practice the printx will be likely to finish first, because starting a new thread takes a huge amount of time relative to the time taken for the current running thread to do a litle arithmetic, get the (uncontended) lock for the console and write to it.
It is a race condition, though, and it would be a really bad idea to rely on either thing happening first. If a program runs enough times all kinds of interleavings may happen. There's no guarantee which thing will happen first here, it would be better to avoid making assumptions.
There's another issue. The constructor is called by the main thread, initializing x, then starting a new thread. The new thread modifies x in the run method, but there isn't anything requiring making the contents of x visible to the new thread. Making x volatile would make its contents visible.
And yet another issue: the arithmetic operations take multiple steps to be executed and can be interfered with by the other thread. It's not just a question of which operation will happen first, they could be interleaved. Fixing this would require locking or using atomicInteger.

ConstructorOrRun() returns immediately, on the main thread, and then printX() is invoked.
There's no guarantee that calling start() in the constructor will cause run() to start, let alone finish (on a different thread), before the constructor returns. In fact, I'd be surprised if it did.

Related

Unsafe access from multiple threads to set a single value to a single variable

I understood that reading and writing data from multiple threads need to have a good locking mechanism to avoid data race. However, one situation is: If multiple threads try to write to a single variable with a single value, can this be a problem.
For example, here my sample code:
public class Main {
public static void main(String[] args) {
final int[] a = {1};
while(true) {
new Thread(new Runnable() {
#Override
public void run() {
a[0] = 1;
assert a[0] == 1;
}
}).start();
}
}
}
I have run this program for a long time, and look like everything is fine. If this code can cause the problem, how can I reproduce that?
Your test case does not cover the actual problem. You test the variable's value in the same thread - but that thread already copied the initial state of the variable and when it changes within the thread, the changes are visible to that thread, just like in any single-threaded applications. The real issue with write operations is how and when is the updated value used in the other threads.
For example, if you were to write a counter, where each thread increments the value of the number, you would run into issues. An other problem is that your test operation take way less time than creating a thread, therefore the execution is pretty much linear. If you had longer code in the threads, it would be possible for multiple threads to access the variable at the same time. I wrote this test using Thread.sleep(), which is known to be unreliable (which is what we need):
int[] a = new int[]{0};
for(int i = 0; i < 100; i++) {
final int k = i;
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(20);
} catch(InterruptedException e) {
e.printStackTrace();
}
a[0]++;
System.out.println(a[0]);
}
}).start();
}
If you execute this code, you will see how unreliable the output is. The order of the numbers change (they are not in ascending order), there are duplicates and missing numbers as well. This is because the variable is copied to the CPU memory multiple times (once for each thread), and is pasted back to the shared ram after the operation is complete. (This does not happen right after it is completed to save time in case it is needed later).
There also might be some other mechanics in the JVM that copy the values within the RAM for threads, but I'm unaware of them.
The thing is, even locking doesn't prevent these issues. It prevents threads from accessing the variable at the same time, but it generally doesn't make sure that the value of the variable is updated before the next thread accesses it.

Why is 'create' asynchronous?

I was told, that creating a new instance is always an async message; but I don't understand why.
e.g.:
Foo myFoo = new Foo();
Here I will have to wait until the constructor finishes and returns my new object. But doesn't asynchronous mean, that I go on independently (no waiting) - like starting a thread?
I was told, that creating a new instance is always an async message;
Sorry, I have to say that either you heard it wrong or you were told something that is wrong. But first off, we should get some terminology straight. The term "async" or "asynchronous" means that the invocation returns immediately to the caller. We can easily demonstrate that this is not true with a constructor, with a simple experiment [1]. In other words, the constructor must return for the caller to make any progress.
Starting a thread is indeed asynchronous. The call to Thread.start() returns immediately and at some later point in time the thread actually starts running and executing the run() method.
1 The Experiment
Consider your class (for illustration only) is like below:
Foo.java
class Foo {
Foo() throws InterruptedException {
while (true) {
System.out.println("not returning yet ...");
Thread.sleep(2000);
}
}
public static void main(String[] args) throws InterruptedException {
Foo foo = new Foo();
}
}
If you compiled and run this class (I used Java 8 on my Mac, but that is not a requirement). As expected, this class runs forever producing the output every 2 seconds:
not returning yet ...
not returning yet ...
not returning yet ...
not returning yet ...
Note that the sleep call was added just to make it bearable. You could try this experiment without it, but then your program will overwhelm one of the CPU's by stressing it to 100%.
If, while it is running, you took a thread dump (for example, by using the command jstack), you see something like below (curtailed for brevity):
"main" #1 prio=5 os_prio=31 tid=0x00007f9522803000 nid=0xf07
waiting on condition [0x000000010408f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at Foo.<init>(Foo.java:5)
at Foo.main(Foo.java:9)
Regardless of the state of the thread (RUNNABLE, BLOCKED, WAITING, TIMED_WAITING), you will always see (take various thread dumps to see what this means) you will always see these two lines:
at Foo.<init>(Foo.java:5)
at Foo.main(Foo.java:9)
which means that the caller (in this case, the main thread) will never make any progress. And since this constructor never returns, no progress happens.
I was told, that creating a new instance is always an async message;
No, java constructors doesn't have implyed synchronization. Anyway, you can have concurrency issues within it. There is not guarantee that all the fields are initialized after the constructor call.
Here I will have to wait until the constructor finishes and returns my new object. But doesn't asynchronous mean, that I go on independently (no waiting) - like starting a thread?
Nope, you don't have to wait. You can access the object within another thread.
I suggest you to read this thread.
Example for concurrent access to an object while the constructor is still executing:
public class Demo {
private volatile int constructionCounter;
private volatile String string;
public Demo() throws InterruptedException {
super();
assert this.constructionCounter == 0;
this.constructionCounter++;
// From this point on, there's no way the constructionCounter can ever be != 1 again, because the constructor will never run more than once, concurrently or otherwise.
assert this.constructionCounter == 1;
final Demo newInstance = this;
Thread t = new Thread( new Runnable() {
public void run() {
// Access new instance from another thread.
// Race condition here; may print "Hello null" or "Hello World" depending on whether or not the constructor already finished.
System.out.println("Hello " + newInstance.getString());
}
});
t.start();
this.setString( "World!" );
}
public String setString( String str ) {
this.string = str;
}
public String getString() {
return this.string;
}
}
Note that this is only ever possible if and when the constructor itself somehow hands this out to another thread.

How does a thread know that there is a join method ahead

Below is my sample code, when my a.start() called it should create a thread and print "Run" immediately. But why does is called after printing "begin" 20 times.
How does thread "a" decide that it doesn't have to call run() immediately.
public class JoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
for (int i = 0; i < 20; i++) {
System.out.print("Begin");
}
Thread.sleep(1000);
a.join();
System.out.print("\nEnd");
}
public void run() {
System.out.print("\nRun");
}
}
Output:
BeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBeginBegin
Run
End
I am little confused about the behavior of thread.
In my opinion "run" should be printed before "begin" because it get printed before the join() method is called, and at the time of join method called thread "a" must have finished its execution and calling join must be useless at that point.
Calling start() on a thread doesn't necessarily triggers the execution of its run() method immediately. Your thread is marked as started but the main thread pursues its execution into the for loop. Then the JVM is switching to your thread once the main thread reaches the sleep() statement.
You start the thread, then immediately do some printing, then sleep. Looking at your code I would actually expect to see Begin before Run because the thread is being started in the background, concurrently to your main thread going on with its work. Futhermore, the print method is synchronized so you repeatedly acquire that lock in a loop, giving even less chance to the second thread to interject.
I have tried your code with Thread.sleep eliminated, both with and without the join call. The behavior is the same in both cases: Run comes at the end most of the time and occasionally manages to get interleaved between the Begin words. Everything exactly as expected by the simple model of concurrency with synchronized blocks.
Here is a slight variation on your code which reliably prints Run before everything else, whether you call the join method or not. All that changed is the position of the sleep call.
public class JoinTest implements Runnable
{
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
Thread.sleep(1000);
for (int i = 0; i < 20; i++) {
System.out.print("Begin");
}
a.join();
System.out.print("\nEnd");
}
public void run() {
System.out.print("\nRun");
}
}
The start() method calls the thread's run() method, although this takes a little time, which may just be enough for some or all of your 'Begin' loops to complete. When I run this on my machine the 'Run' output appears between the first and second 'Begin'. Try outputting with timestamps so you can see how long your machine is taking to execute each command:
public class JoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new JoinTest());
a.start();
for (int i = 0; i < 20; i++) {
System.out.println("Begin " + System.nanoTime());
}
Thread.sleep(1000);
a.join();
System.out.println("End " + System.nanoTime());
}
public void run() {
System.out.println("Run " + System.nanoTime());
}
}
Calling a.join() at that point ensures that you will always see 'Run' output before 'End', as join() waits for the thread to complete.
I have tried many scenarios with join(), "run" always get printed after "begin" but when i remove the join statement "run" always get printed before "begin". Why?
Because it's allowed. That's why. As soon as you call .start(), you have two threads. Untill your program calls a synchronization methods like .join() it's entirely up to the JVM implementation and the operating system to decide which thread gets to run when.
The a.join() call from your main thread forces the main thread to wait until the a thread has completed its run() method.
Without the a.join() call, the Java Language Specification permits the a thread to complete its work before a.start() returns in the main thread, and it permits the main thread to reach the end of the main() function before the a thread even begins to run, and it permits anything in between to happen.
It's entirely up to the JVM and the OS.
If you want to take control of the order in which things happen, then you have to use synchronized blocks, and synchronization objects and method (e.g., .join()).
But beware! The more you force things to happen in any particular order, the less benefit your program will get from using threads. It's best to design your program so that the threads can function independently of one another most of the time.

Is this okay to do with threads and blocking queues?

I was wondering if it was okay that you give a thread access to an instance of a class
so you can perform operations on certain members/variables of that class.
For example, I have both a main thread and a thread.
I'm giving the second thread access to the instance of the main class
so I can perform an operation on x.
However, what if at some point in the future I decide to do operations on x
in the main thread? Or just simply reading from x. What if both the other thread and the main
thread want to read x at the same time?
Is this at all okay by the way I have it structured in my code to do?
package test;
import java.lang.Thread;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class AThread extends Thread {
Test test;
AThread(Test test) {
this.test = test;
}
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
public void run() {
String msg;
while ((msg = queue.poll()) != null) {
// Process the message
//System.out.println(msg); //should print "hello"
if (msg.equals("up")) {
test.setX(test.getX()+1);
System.out.println(test.getX());
}
}
}
}
public class Test {
AThread aThread;
private int x = 5;
void setX(int x){
this.x = x;
}
int getX(){
return x;
}
Test() throws InterruptedException{
System.out.println("MainThread");
aThread = new AThread(this);
aThread.start();
while (true) {
aThread.queue.put("up");
}
}
public static void main(String[] args) throws InterruptedException {
new Test();
}
}
And not just the member 'x', but also there could be more members in class "Test" that I'd want to be able to perform operations on such as reading/writing.
Is this an okay structure to do so? If not, what should be fixed?
There are several problems with your code.
Consider this line:
aThread = new AThread(this);
It is always a bad idea to pass this somewhere in a constructor. And this has nothing to do with the threads... yet. The reason is that the 'somewhere' may call a method on this, and the method could be overridden in a subclass whose constructor wasn't called yet, and it may end up in disaster because that override may use some of the subclass fields that aren't initialized yet.
Now, when threads come into the picture, things get even worse. A thread is guaranteed to have correct access to a class instance that was created before the thread is started. But in your case, it isn't created yet, because the constructor is not finished yet! And it's not going to finish anywhere soon because of the infinite loop below:
while (true) {
aThread.queue.put("up");
}
So you have an object creation running in parallel to a startup of a thread. Java doesn't guarantee that the thread will see the initialized class in such case (even if there was no loop).
This is also one of the reasons why starting threads in constructors is considered a bad idea. Some IDEs even give a warning in such cases. Note that running infinite loops in constructors is probably a bad idea too.
If you move your code into a run() kind of method and do new Test().run() in main(), then you code will look fine, but you are right to worry about
However, what if at some point in the future I decide to do operations
on x in the main thread?
The best idea is for the main thread to forget about the object right after it is passed to the thread:
public static void main(String[] args) throws InterruptedException {
AThread aThread = new AThread(new Test());
aThread.start();
while (true) {
aThread.queue.put("up");
}
}
However, what if at some point in the future I decide to do operations on x in the main thread? Or just simply reading from x. What if both the other thread and the main thread want to read x at the same time?
Any time you are sharing information between two threads, you need to provide for memory synchronization. In this case, if you make int x be volatile int x then your code should work fine. You should read the Java tutorial on the subject.
However, if the thread is doing more complex operations, as opposed to just setting or getting x, then you may need to make the method be synchronized or otherwise provide a mutex lock to make sure that the 2 threads don't overlap improperly.
For example, if you need to increment the value of x, a volatile won't help since increment is actually 3 operations: get, increment, and set. You could use a synchronized lock to protect the ++ or you should consider using an AtomicInteger which handles incrementAndGet() methods in a thread-safe manner.
#Segey's answer gives some great feedback about the rest of your code. I'll add one comment about this code:
while (true) {
aThread.queue.put("up");
}
You almost never want to spin like this. If you want to do something like this then I'd add some Thread.sleep(10) or something to slow down the adding to the queue or make the queue bounded in size. It is likely that you are going to run out of memory spinning and creating queue elements like this.

Correct use of wait()/notify() for a Tetris game

I’m writing a Tetris-like game for Android and I’m trying to implement the “real-time part”. I have something which seems to work, but I want to be sure that my implementation is correct.
What I want is:
The shapes are going down at a fixed rate (say that I want to wait n milliseconds each time the y of the shape is decremented)
The player can drop the shape at any time and the timer waiting for the n milliseconds must then be immediately interrupted and start again only for the next shape
When the shape is droped or when the shape cannot go down anymore, the game waits m milliseconds before creating another shape
The system have to be able to stop the thread at any time
What I am doing is the following (the system can stop the thread with interrupt()):
class TetrisThread extends Thread {
private int n = 3000; // for testing purposes, in the real game n will be smaller ;)
private int m = 1000;
#Override
public void run() {
doDraw();
while(!interrupted())
{
try {
synchronized (this) {
wait(n);
}
doPhysics();
doDraw();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// This method is the one which will drop the shape, it is called from another thread
synchronized public boolean onTouch([…]) {
[…]
// The shape has to be dropped
dropShape();
notify();
[…]
}
private void doPhysics() throws InterruptedException {
[…]
// The shape cannot go down or has been dropped
sleep(m);
createNewShape();
[…]
}
}
In particular, the part synchronized(this) { wait(n); } looks funny because if I understand correctly this will take a lock on this and release it immediately.
But wait() requires to be used in a synchronized(this) block (why?) and I cannot either synchronize the whole run() method, because then if I try to drop three times the shape during the sleep(m) call, then the three next shapes will be automatically dropped (which is not what I want).
Does this seem correct to you?
Do you have any correction, advice, or remark?
Thank you :-)
The wait() method is used to make the current running thread to wait the object invoking wait() invoke notify() (in this case this). The synchronized(this) part needed to make sure only one thread at that time accessing this.
You can't synchronize the whole run() method, because the run() is from the parent (Thread) class and the parent didn't use synchonized in the declaration.
I don't know how to solve your other problem because I don't get how your program works right now.

Categories