Thread and super keyword - java

The following code will output Program A. Kindly explain it w.r.t super.run();.
class RunnableA implements Runnable{
public void run(){
System.out.println("Program A");
}
}
class MyThread extends Thread{
MyThread(Runnable r){
//set as a target
super(r);
}
public void run(){
//System.out.println("MyThread");
super.run();
}
}
class Demo{
public static void main(String args[]){
RunnableA a1=new RunnableA();
//a1.start(); //Illegal
new MyThread(a1).start();
}
}

super.run(); means that MyThread's run() method executes Thread's run() method (which calls the run() method of the Runnable instance that was passed to the constructor).
Therefore new MyThread(a1).start(); executes RunnableA's run() method and prints "Program A".
In this example MyThread is quite useless, as it doesn't add any functionality to Thread. You can replace your main method with :
public static void main(String args[])
{
RunnableA a1=new RunnableA();
new Thread(a1).start();
}
and get the same behavior.

Related

Define method with object instantiation in java

I'm slowly transitioning from C++ to java and I do not understand the following piece of code:
public class TestThread
{
public static void main (String [] args)
{
Thread t = new MyThreads()
{
public void run()
{
System.out.println(" foo");
}
};
t.start();
System.out.println("out of run");
}
}
An object type "MyThreads" is being instantiated, but what does the function "void run" mean?
Why is it written using that syntax right after the object instantiation?
Is that function being overriden?
When is this kind of syntax (where I define a function with an object instantiation) necessary/required? and where is it preferred/useful?
It means that the class MyThreads either require you to first write a method with name run or the way you are doing provides the ability to change the existing run method behaviour where you are declaring.
It is like overriding if run method is already there or creating the method when you want to create object.
This provides the ability to create objects of MyThreads without having to change the original class or creating multiple classes.
public class TestThread
{
public static void main (String [] args)
{
Thread t = new MyThreads()
{
public void run()
{
System.out.println(" foo");
}
};
t.start();
Thread t1 = new MyThreads()
{
public void run()
{
System.out.println(" this time it is somethidn else");
}
};
t1.start();
System.out.println("out of run");
}
}
Little modification to your code shows the advantage of having this feature. If you observe run method of t1 is doing something different than what is in t. So it is now completely new thread.
This code is equivalent to
public class TestThread
{
static class MyThreadSubclass extends MyClass {
public void run() {
System.out.println("foo");
}
}
public static void main (String [] args)
{
Thread t = new MyThreadSubclass();
t.start();
System.out.println("out of run");
}
}
It's just a convenient way of defining a subclass inline, without having to give it a name; it's just syntactic sugar. It's creating an object of a subclass that overrides the method run() from MyThreads.

implementing thread using runnable interface in java

Why we have to create an instance of a class and attach it to the newly created thread object even if both are in the same class?
import java.io.*;
class thread1 implements Runnable{
public void run(){
System.out.println("thread started");
}
public static void main(String args[]) throws Exception{
Thread t1=new Thread(new thread1());
t1.start();
}
}
You don't have to create a Runnable to perform custom code within a new Thread. It's also possible to create a subclass of thread directly.
public class WorkerThread extends Thread{
#Override
public void run() {
// TODO Auto-generated method stub
super.run();
// DO SOMETHING
}
}
public class MainClass {
public static void main(String[] args){
new WorkerThread().start();
MainClass mc = new MainClass();
mc.startThread();
}
private void startThread(){
Thread t = new WorkerThread();
t.start();
}
}
I think you have two questions in one:
1.) How to work with a Thread in Java? The answer of Fizer Khan is an example of this.
2.) How do static methods work in java? If you have a static method you are, in a maner of speaking, on a "static layer". You have no "this" reference because there is not object on this layer. Only if you create an instance you can access instance fields and non static methods on this object.
If you add a second static method, you can do the same stuff as in your main method, because both are static. This is rudementary look at this question: https://stackoverflow.com/questions/18402564/how-do-static-methods-work
pulblic class Thread1 implements Runnable{ //name should be upper case
public void run(){
System.out.println("thread started");
}
public static void main(String args[]) throws Exception{ //static method
Thread t1=new Thread(new Thread1()); //t1 is a local reference to an object on the heap - no specil magic here
t1.start(); //call to an "instance" method, can only be performed on an object.
}
There are two ways to write threads.
public class ThreadX implements Runnable {
public void run() {
//Code
}
}
/* with a "new Thread(new ThreadX()).start()" call */
public class ThreadY extends Thread {
public ThreadY() {
super("ThreadY");
}
public void run() {
//Code
}
}
/* with a "new ThreadY().start()" call */
public class MainClass {
private Thread threadX = new Thread(new ThreadX());
private Thread threadY = new ThreadY();
public static void main(String[] args){
// Call threads
threadX.start();
threadY.start();
// some more threads
new Thread(new ThreadX()).start();
new ThreadY().start();
}
}
When you extends Threads, You usually extend a class to add or modify functionality. So, if you don't want to overwrite any Thread behavior, then use Runnable.

Why is the constructor of a class which implements Runnable Interface not called?

I tried using the constructor of a class which implements Runnable Interface. But I was surprised to see it was never called. The run() method was called, however, the constructor was never called. I have written a simple sample code to show the phenomenon. Can anyone explain why this is happening?
public class MyRunner implements Runnable {
public void MyRunner() {
System.out.print("Hi I am in the constructor of MyRunner");
}
#Override
public void run() {
System.out.println("I am in the Run method of MyRunner");
}
public static void main(String[] args){
System.out.println("The main thread has started");
Thread t = new Thread(new MyRunner());
t.start();
}
}
Change public void MyRunner() to public MyRunner() (no return type). public void MyRunner() is not a constructor, it's a method. Constructor declarations don't have a return type.
You have a default Constructor there, since you don't define any constructor. And, the default Constructor was called internally.
A Constructor can't have return type. In your case, public void MyRunner() {} is a method. remove void from you Constructor signature.
Constructor is a special method which does not have return type and its name is same as Class name so remove void from method name to make it constructor.
public class MyRunner implements Runnable {
public MyRunner() {
System.out.print("Hi I am in the constructor of MyRunner");
}
#Override
public void run() {
System.out.println("I am in the Run method of MyRunner");
}
public static void main(String[] args) {
System.out.println("The main thread has started");
Thread t = new Thread(new MyRunner());
t.start();
}
}
This will work and your constructor will be called.

Method Overriding using super keyword

I have one doubt, Please see the following code. i have three classes A,B and InheritanceExample. Here I am calling the super.run() from the main class; it is calling the B class run() method.
Is there any option to call A class run method from the main class (InheritanceExample) with out creating an instance for class A?
class A
{
void run()
{
System.out.println("<<<====Class A run Method===>>>>");
}
}
class B extends A
{
void run()
{
System.out.println("<<<====Class B run Method===>>>>");
super.run();
}
}
public class InheritanceExample extends B{
/**
* #param args
*/
void run()
{
System.out.println("<<<====Main Class run Method===>>>>");
super.run();
}
public static void main(String[] args) {
InheritanceExample a = new InheritanceExample();
a.run();
}
}
Since B extends A and InheritanceExample extends B you are creating an instance. Make method A.run() static.
class A
{
void static run()
{
System.out.println("<<<====Class A run Method===>>>>");
}
}
class B
{
void run()
{
System.out.println("<<<====Class B run Method===>>>>");
A.run();
}
}
public class InheritanceExample extends B {
#Override
void run()
{
System.out.println("<<<====Main Class run Method===>>>>");
super.run();
}
public static void main(String[] args) {
InheritanceExample a = new InheritanceExample();
a.run();
}
}
No.
Not without making A.run() different from B.run(), such as by making A.run() static.
When B extends A, you as a programmer must ensure that from the callers perspective B "is-a" A. What you want to do is to break this rule.
If you want to use a B as an A, you are probably trying to do something at the calling point, that should be handled internally in B.
Not sure what you want to achieve. But looking at the class hierarchy and structure, it is not possible to directly call run method of Class A. But if we change and introduce a additional static method say runImpl in Class A, and call same method from run method of Class A. Now we can call runImpl from anywhere as it is static and run method too internally is calling runImpl so same implementation is getting call via run and runImpl.
Below is the code snippet:
class A
{
void run()
{
runImpl();
}
public static void runImpl(){
System.out.println("<<<====Class A run Method===>>>>");
}
}
class B extends A
{
void run()
{
System.out.println("<<<====Class B run Method===>>>>");
super.run();
}
}
public class InheritanceExample extends B{
/**
* #param args
*/
void run()
{
System.out.println("<<<====Main Class run Method===>>>>");
super.run();
}
public static void main(String[] args) {
A.runImpl();
}
}
class a{
void run(){
System.out.println("runing method run of a clss");
}
}
class b extends a{
void run(){
super.run();
System.out.println("runing method run of b clss");
}
}
class InheritanceExample extends b{
void run(){
super.run();
System.out.println("running method run in inheritance class");
}
}
class pratics{
public static void main(String[] args){
System.out.println("********");
InheritanceExample a1=new InheritanceExample();
a1.run();
System.out.println("********");
}
}

Callback from new thread to class from which thread was initiated

I have a class from which I am calling a new thread.
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
//Do Something
//After this I would like to notify my MainClass that some thing has been done and pass a value.
}
}
}
private void callbackFunc(int a){
// Do something based on value of a
}
}
I have a function in my MainClass. But how do i call this function from my new thread, so as to receive a callback.
Thanks.
You should just be able to call the method in MainClass by its name just as if you were calling from directly inside MainClass itself (as opposed to from the inner class).
If a method name you want to call happens to conflict with one that your inner class has inherited from Object then you can prefix the call with MainClass.this, e.g. MainClass.this.toString() calls toString on MainClass, whereas just toString() calls it on the inner class instance.
In such a case pass the instance of MainClass to the thread class ((during creation)) so that it can call method on it. Having inner class as suggested by others is also a good option.
Something similar-
class MainClass {
private void cleardata() {
new Thread(new MyThread(this)).start();
}
}
class MyThread implements Runnable {
private MainClass mc;
MyThread(MainClass mc) {
this.mc = mc;
}
public void run() {
// do something
// mc.someMethod();
}
}
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
callBackFunc(result);
}
}
}
private void callBackFunc(int a) {
}
}
Just do it:
public class MainClass{
private void cleardata() {
// do something on a separate thread
new Thread(new Runnable() {
#Override
public void run() {
//Do Something
notifyTheClass("a parameter");
}
}
private void notifyTheClass(String aParam) {
//..do something else
}
}
}
But it is not related to threads, this is about inner classes. If you want the main thread to wait until the new thread is finishes, use Futures for a result. Or use some other multithreading primitives.

Categories