I am going through Hello Android (Android PDF/tutorial) and have now seen this syntax a couple of times. Can someone please explain to me what Java syntax is used when run Runnable is defined?
private class AndroidBridge {
public void callAndroid(final String arg) { // must be final
handler.post(new Runnable() {
public void run() {
Log.d(TAG, "callAndroid(" + arg + ")" );
textView.setText(arg);
}
...
Is the code defining a Runnable object and overriding it's run method?
As Dave Newton indicated, this is an anonymous inner class implementing the Runnable interface.
As to why one would want to use this, it could be thought of as syntactic sugar of sorts. You'll notice that in your example, the code in run() has access to the same scope as where the anonymous inner class itself is defined.
This simplifies access to those members, as if you defined the class externally, you'd have to pass in a reference to any object whose members you wanted to invoke/use.
In fact, IIRC, this is actually what happens when Java compiles the anonymous inner class; if there are references to the outer containing class, the compiler will create a constructor that passes in a reference to the outer containing class.
The .post method expects a Runnable object, which in your code sample is declared anonymously and passed as the argument.
That will start a new thread for some long-running process.
The thread constructor needs a Runnable object, which has a run method that's called when the thread is ready.
When many Java apps start, all of the operations pile up on one thread, including the UI. I mainly use threads to avoid freezing up the UI if I'm doing something "heavy".
You've seen this happen when you click "execute" or something, and the UI suddenly is less than responsive. This is because the current thread doesn't have enough resources to build the UI and do whatever "execute" is asking.
So, sometimes that's done elsewhere, on a different thread, which needs a Runnable object.
It's worth noting that multithreading (where you make more than one thread on purpose) is notoriously difficult to work with, for debugging reasons mostly, IMO. But it is a useful tool, of course.
The code is defining an anonymous inner class that implements the Runnable interface, and implementing the run method to perform the appropriate actions.
Related
Say I have class A which is not thread safe, and I want to launch a bunch of threads with class B, is passing a new instance of class A to each thread of class B a good design choice, since if I passed one instance of class A to all of them there would be concurrency issues?
#NotThreadSafe
class A {
...
}
class B extends Thread {
private A a;
B(A a) {
this.a = a;
}
}
class C {
public static void main(String [] args) {
for(int i = 0; i < 10; i++) {
A a = new A();
B b = new B(a);
b.start();
}
}
}
It pretty much depends on the characteristics of class A.
In general, passing creating an instance of A per thread will solve (not solve, but rather eliminate) concurrency issues.
Assuming class A has some internal state (otherwise class A itself is supposed to be thread safe), each thread B will read/update different fields in memory that belong to its "own" object of class A, so no concurrency issue here, unless...
A is very "heavy" object and creating it will have a big performance / memory impact.
Using design of object per thread won't meet the functional requirements of the product. For example, you have to share something between threads (somthing = some common state) because if one thread B, say, has done some work and has updated that internal state, another thread B should be able to benefit from (be able to read) that state otherwise it will do that work again or do it in a wrong.
Let's assume that you have overridden run in the B class. Your example doesn't make sense otherwise. (The start() call would invoke Thread::run which returns immediately. Ooops!)
Some terminology first.
A thread confined object is an object is an object whose state is accessible to one and only one thread.
If an object is thread confined, then it doesn't matter if the class is thread-safe or not.
(Depending on how broadly you define "state" of course. Lets assume that the object's state is the closure of the object that the object's methods may access. Or something like that.)
So what we have in your example is a non-thread-safe object a that is created in main and then used solely in a single child thread.
Prior to the start() call, each a is thread confined to the main thread. For this part of the program, thread-safety (of A) doesn't matter.
Once control reaches the child thread's run() method, each a is thread confined to the child thread. From then on, thread safety doesn't matter.
Now what about the start() call itself?
The Java Memory Model (JLS 17.4) specifies that there is a happens-before relationship between the call to start() in the main thread, and the call to run() in the child thread. This happens-before ensures that writes to the A or B instances or anything else made by the main thread prior to the start() call are guaranteed to be visible to the child thread on / after entering the run method body. This is a strong guarantee. Any compliant Java 5.0 or later implementation will behave this way, on any platform.
However, changes made to the A, etc in the main thread after the start() call are not guaranteed to be visible to the child. They may or may not be. If that happens, your code is likely to be broken. But the example code doesn't show it happening.
In summary, this approach is thread-safe. Whether it is "viable" depends on whether your design meets the requirements. For example, the B threads need to share state, this approach doesn't address that.
Finally, extending Thread is generally thought to be a bad idea. A better idea would be to instantiate plain Thread instances, passing them a Runnable as a constructor parameter. Alternatively, use an ExecutorService and let that take care of thread management.
There is a big difference between using a single instance and a new instance each time. (Eg if the class represents a Person then, it's the difference between the same person or a different one every time. This makes the program outcome different between circumstances and this question therefore doesn't make sense.)
If we assume the class holds no data and therefore the program outcome will not change whether or not a single instance or multiple are used, then
a good design choice, since if I passed one instance of class A to all
of them there would be concurrency issues
it would be a terrible design choice and not solve any concurrency issues, as the external data each class instance works on will still be the same and the threads will fight over the data.
To fix concurrency issues you must use synchronization.
I was reading a textbook and I was wondering how come the argument we pass to the function is neither a primitive or an user-defined instance of a class.
SwingUtilities.invokeLater(new Runnable()
{
public void run() {
new ButtonDemo();
}
});
I have learned that it was either one of those two. But it seems here that it passes an user-defined constructor method, e.g. Runnable(). It seems they want to run the thread at a later time, but when? And is this even legal, I assume it is, but I never heard of such a thing in my Java class.
This is actually passing an instance of an anonymous inner class implementing the Runnable interface. Read about them in the Java tutorial.
I was wondering how come the argument we pass to the function is neither a primitive or an user-defined instance of a class.
It is an instance of a user-defined class. The only difference is that this class does not have a name *.
It is a real instance of a class, though - it can do most of the things a named class can do. Among other things, it can provide implementations of methods of its base class or an interface, which is what is used to pass "a piece of executable code" to a method.
* At least, not a user-visible one: Java compiler does assign each anonymous class an internal name, which usually contains a dollar sign.
The code inside SwingUtilities is something like this
private Runnable runnable;
private void invoke(){//called at some point from inside the runnable
runable.run();
}
public void invokeLater(Runnable runnable){
this.runnable=runnable;
}
These are called callbacks.
This called anonymous class, where you define a class for a single use and do not provide it a name.
To understand them better, refer to this tutorial: http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
Read about Anonymous Classes. This are treated as separate classes. If you compile your code and say the file name is Test.java. By compiling there will two class file Test.class and Test$1.class and if you have more inner classes you will have Test$2.class, Test$3.class and so on.
Passing code as function arguments
Java will have lambda expressions in release 8. It will worth checking out this as well: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
Why was the Thread class implemented as a regular class and not an abstract class with run() method being abstract.
Will it possibly introduce any problems? Or does it have any use in being this way?
Also, the Thread.start() method is supposed to be a very specific method whose functionality cannot be implemented by any other class (If I am not wrong). And hence I guess the final keyword would be apt for this more than any other method.
But I am able to override this method and use it as I like,
public class Test extends Thread {
public static void main (String... args) {
Thread test = new Test();
test.start();
}
#Override
public void run() {
System.out.println("New thread started...");
}
#Override
public void start() {
System.out.println("Did anyone tell you I will spawn a new thread??");
}
}
It obviously only printed,
Did anyone tell you I will spawn a new thread??
Is there any use in overriding other than confusing the engineer replacing you?
If not, why was the method not declared final in Thread class?
You can of course choose to shoot yourself in the foot, but that doesn't mean you must.
Why was the Thread class implemented as a regular class and not an abstract class with run() method being abstract.
Because the recommended way to create a start a thread is not to subclass Thread. The recommended way is to define a Runnable, and pass it as argument to the Thread constructor:
Runnable r = new Runnable() {
#Override
public void run() {
...
}
};
Thread t = new Thread(r);
t.start();
And hence I guess the final keyword would be apt for this more than any other method.
Yes and no. You can't replace the implementation of start() by your own implementation, but you can do additional things in start() if you want:
#Override
public void start() {
System.out.println("Did anyone tell you I will spawn a new thread??");
super.start();
}
That said, if Java was redesigned from scratch today, there is a good chance the design would be different. Remember that this class dates from Java 1.0, and is still backward-compatible.
Why was the Thread class implemented as a regular class and not an
abstract class with run() method being abstract.
This question actually boils down to the fact that you should always prefer composition over inheritance.
If the Thread class was declared as abstract, the language would have to provide another class that extended from it which programmers could use to create a Thread. Your question would then be about why this class that extends from Thread is not abstract. If the language did not provide another class that extends from Thread, programmers would have to create their own class that extends from Thread and override the run() method.
If not, why was the method not declared final in Thread class??
The only possible explanation I can give is that the developers of the language saw some use-cases for overriding start when the class was introduced to the JDK. The first version of Java that I used was 1.5 and I personally have not come across a use-case where I found the need to override start. As JB Nizet stated in his answer
if Java was redesigned from scratch today, there is a good chance the design would be different
Why is Thread.start() not final?
Are you sure you would never want to override it?
Class MyThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new Thread(r) {
#Override
public void start() {
LOGGER.info("Starting thread " + this);
super.start();
}
};
}
}
I feel a few calirifcations should be posted for the answers :
"Are you sure you would never want to override it?"
No ! I would not. Thats like saying, "Are you sure , you want to declare this variable private?" Because if I could declare any variable I use as public without fearing that other developers may mess my design logic, coding would be a breeze. One of the most important purpose of OOPS concepts of Scope, abstraction, polymorphism, Error handling etc is to communicate to other developers the design and intentions behind your code.As pointed out in the question, when you override start method, nobody is forcing you to use super.start(). #Codebender wrote a start method for a thread without using super.start() and compiler never complained. So he is free to break the whole mechanism of Threading and compiler is suppose to just let it pass? Thread's start method ensures that run method is called and execute at the right time ! It is critical to the very concept of Threading. I would be more than happy to be corrected, if I missed something here.
2.
Because the recommended way to create a start a thread is not to
subclass Thread.
OK, if codebender is allowed by design, to sublass Thread and mess up the start method, By that logic, it is the design shooting itself in the foot.
By another statement made,(which I agree with completely) , Runnable is the recommended way. Then why do we allow Thread class at all to instantiate the thread at all with no restrictions? This is followed by :
You can't replace the implementation of start() by your own
implementation,
That actually supports codebender's claim that start method should be final when you say that.. ^
The one point, that's valid, is mentioned already as a side note, but is the actual answer to this question
"Backward compatibility".
In fact, improvements were even going on as late as JDK 5.0 , when they incorporated many major additions and clarifications to the Java concurrency model. We want backward compatibility to be supported all the way and thats why Thread class is still exactly as it was before, even though Runnable interface is the recommended way nowadays.
Again, I would be more than happy to be corrected, if I missed something.
I tried really hard to search for information about the issue, but nothing was relevant.
Any contribution will be appreciated.
DataStructure ds = new DataStructure();
public synchronized void run() { b(); }
private void b() { ds.update(); }
public synchronized void c() { ds.update(); }
Suppose that the above code is implemented using a thread.
as you might notice, there is a DataStructure object which is being shared and accessed through synchronized methods, when only one synchronized method can be called at any given time (I am not mistaken. right?).
Is there any possibility that the DataStructure object will be accessed through the public methods in unsynchronized manner?
thanks.
Your code is incomplete, but if the above is part of a Runnable or Thread, then no concurrency is possible with the given methods since you're synchronizing the entire run() method. Using threads is pretty pointless in that case.
I also don't see where the DataStructure would be shared between threads - looks like a separate one is created for each one. If it actually is shared, then access would not be synchronized because you synchronize on the Runnable or Thread rather than the shared object.
Without seeing more code, its very hard to tell. What is the class that those methods belong to? how are they invoked, and by what classes?
Concurrency problems are hard to diagnose, and harder if there isn't enough information.
What i assume you have are threads that execute the run() method above, and there are different threads that execute the c() method. The synchronization happens on the class that the above method resides, so there wouldn't be any problems (except slowness if lots of threads).
If
There is no other public method apart from what you wrote here, that has access to ds, and
"the DataStructure object" you are talking on is the object instance in a specific object instance of your class (instead of ALL DataStructure objects)
then what you are expecting is correct. There shouldn't be any concurrent access to ds through public methods of your class.
Honestly I don't see anything special in your class that make it different from normal synchronized method example.
I'm using callables quite often , and I've stubled upon a question that irritates me:
Lets say that to run function foo() , one needs to do a couple of checks first.
Should you
1. Insert the checks as part of the Callable :
class A implements Callable<Long> {
...
public Long call() {
check1();
check2();
return (run());
}
OR , insert all this logic into another class (ALogic) and use the Callable a mere shell for the executor?
class A implements Callable {
...
public Long call() {
ALogic aLogic = new ALogic();
return (aLogic.run());
}
What do you think are the pro's and con's? What do you usually prefer?
My general advice when implementing callback [Java keyword] interfaces is concentrate on making the [non-Java keyword] interface appropriate for the called type. There generally shouldn't be that much in the anonymous inner class (or whatever), but more than just forwarding call.
Also, it's generally not good to have an object that is constructed and then only has a single method called on it. Make it a static method (which may, perhaps, in turn create an object through a private constructor and run that).
Which do you feel is simpler or clearer?
I suggest you do that.
I usually prefer to simply forward the callback to a private method on the enclosing class. This eliminates the "this" reference that simply points to the anonymous inner class, which is pretty useless.