understanding java code for thread - java

I was just reviewing some java code and I came across the below program
public class LengthOfString extends Thread {
static String s;
public void run(){
System.out.println("You Have Enter String: " + s +" Length Of It is :" + s.length());
}
public static void main(String[] args) throws InterruptedException {
s = "This IS String";
LengthOfString h = new LengthOfString(); //creating the object of class
Thread t = new Thread(h); //why we have passed this object here???
t.start();
}
}
I understood that it is used to print string length, but I have a problem understanding the commented line. Please help me to understand why this implementation was used.

Actually in java, there are 2 ways to create a Thread .
Provide a Runnable object. The Runnable interface defines a single
method, run, meant to contain the code executed in the thread. The
Runnable object is passed to the Thread constructor.
Subclass Thread. The Thread class itself implements Runnable, though
its run method does nothing. An application can subclass Thread,
providing its own implementation of run.
You chosen the second one and you can simply write
new LengthOfString().start();
instead
LengthOfString h=new LengthOfString(); //creating the object of class
Thread t=new Thread(h); //why we have passed this object here???
t.start();
Edit:
Thread class have a constructor public Thread(Runnable target), that it takes Runnable type as a parameter and when you pass that to thread class it calls the implementation of run() method when you start that thread.

In this case, you don't need the Thread t=new Thread(h) line, because LengthOfString extends Thread. Many times though, you implement the Runnable Interface. In that case, you need to create a Thread object with a Runnable argument in the constructor, because Runnable Objects dont have a start methods

Related

Java Multithreading : how does thread creation with Runnable interface work?

Could someone explain what does this code does? new Thread(new X()).start();
Rest of the code:
class X implements Runnable {
X() {}
}
public static void main(String[] arg) {
new Thread(new X()).start();
}
}
This is a very simple example, which shows how to create a new thread and run it. When you create new threads in Java, you give them something to do - a "Runnable".
class X implements Runnable
This interface has only one method - run(). So you create a new thread, with a runnable in its' constructor.
new Thread(new X())
Once you have created a new thread, you have to start it with the start() method. This is when it calls the runnable's run() method. In your example, this has just been chained on after the construction of the thread:
new Thread(new X()).start();
Now, this example is unusual in that class X doesn't actually implement the run method. But normally, there's that extra bit, so your example would look like this:
class X implements Runnable {
public void run() {
System.out.println("This is running on a different thread!");
}
public static void main(String[] arg) {
new Thread(new X()).start();
}
}
You don't need to define a constructor if it's blank, first of all. It'll automatically be blank if you don't define one. Second of all, you can simply do an anonymous class definition, which I'll explain in a second. The method isn't main in this case, it's run. You can define a thread object using the anonymous class definition, too.
new Thread() {
#Override
public void run() {
//Code here
}
}.start();
The anonymous class definition allows you to define and instantiate a class which extends/implements another class both at the same time without actually creating the class. Also, note that X.main() is static, meaning that any instance of X will not have that method. You want to override run and call start. Start is just a method which calls run in a different thread. Note that you can't start a thread twice.
Every thread object has a method run(). if you call the start() method of thread object, then it will execute run().
The only difference is it will be executed separately/parallely and won't be in the existing sequence of operation.
You can create thread in two ways : one by extending Thread and other by implementing Runnable interface.
If you are not extending the Thread class,your class object would not be treated as a thread object. So you have to explicitly create Thread class object.
Thread class will take Runnable class as parameter in constructor.
You are passing the object of your class X that implements Runnable to Thread constructor so that your class run() method will be executed from start() method of Thread.
You can create threads in two different ways. Have a look at oracle documentation about thread creation
An application that creates an instance of Thread must provide the code that will run in that thread. There are two ways to do this:
Provide a Runnable object. The Runnable interface defines a single method, run, meant to contain the code executed in the thread. The Runnable object is passed to the Thread constructor
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Subclass Thread. The Thread class itself implements Runnable, though its run method does nothing. An application can subclass Thread, providing its own implementation of run
public class HelloThread extends Thread {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}

Why can't the the run() method be static in Multi threading?

Am new to multi threading programming, when I declare the run() method as static its giving the compiler error as
"This static method cannot hide the instance method from Thread".
I didn't understand what that means, so please help me.
public class hello extends Thread {
public static synchronized void run() {
for(int i=0;i<1000;i++)
System.out.println(i);
}
public static void main(String[] args) {
hello t1 = new hello();
hello t2 = new hello();
t1.start();
t2.start();
}
}
It is not necessarily relevent to multi-threaded programming, it is true of Java in general. If you have a class:
public class MySuperclass {
public void myMethod() {
//do stuff
}
}
You cannot then over-ride it to make it static:
public class MySubclass extends MySuperclass {
public static void myMethod() {
//do other stuff
}
}
This is not allowed.
That's what the error message means.
public void run();
is a Method declared in class Thread. As it's not static in Thread you cannot "change" it into a static method in your subclass. And given your example, you don't even need to do that.
If you need to have the code executed inside the Thread public and static and synchronized, I'd advise to refactor that part out:
#Override
public void run() {
staticRun();
}
public static synchronized void staticRun() {
for(int i=0;i<1000;i++)
System.out.println(i);
}
In the main() method you create two instances of Thread - t1 and t2 and then you call start() on them and that is correct you cannot run/start the class but an instance. That is why run() method is not supposed to be static. It needs an object (a Thread object) to be executed. Just remove static from your declaration and it shall be almost fine. Other thing is that you dont need to make your run method synchronized (it is counter productive - you use thread to execute in paralel and ynchronize only on specific parts never whole run method).
The instance method run() is already available in hello class due to inheritance. You are trying to create another method (static) with same name which is run().
If the method is not static, it will automatically override the implementation and hide the method instance of parent class..
So, is the Error.. Simple!
Because java is Object Oriented language and anything is java is object.
And task which you are trying to perform in multiple threads is object too and you should create this object. When object is created you should call start() method which is defined on Thread class. So to implement your own logic, you should override this behavior by implementing run() method in Hello subclass.
Run method defines logic which should be performed in other thread (note, that run method doesn't create new thread)
Start method tells java to create new native thread and perform your run method in this new thread
Try:
public class Hello extends Thread{
public void run()
{
for(int i=0;i<1000;i++)
System.out.println(i);
}
}
public class Main
{
public static void main(String[] args)
{
Hello hello t1 = new hello();
Hello hello t2 = new hello();
t1.start();
t2.start();
}
}
The thread Class has a run method, therefore if you define it again in the hello class then you are overriding it, (direct inheritance since Hello extends Thread) now, it makes no sense to turn a Object method into a Class method, (run method belongs to an object and not to the class) that is the reason why your compiler is complaining with the message:
"...you can not This static method cannot hide the instance method
from Thread".
in other words, you are violating inheritance rules with it.

accessing shared variable from inside a Runnable class

I need to define a shared variable in my Main class's main() method. I need two threads to be able to access that shared variable. Im creating the threads by implementing the Runnable interface and implementing the abstract run() method of the interface. How do i refer to the shared variable defined in the Main class's main() method from within the run() method defined in my class that implements the Runnable interface? Obviously just calling them by name is not working - as they appear out of my Runnable class's scope.
EDIT - apologies, here is a simple example
public Class DoThread implements Runnable {
public void run(){
sharedVar += 1
}
}
and in a separate .class file:
public Class Main {
public static void main(String[] args) {
int sharedVar = 0;
Thread t1 = new Thread(new DoThread());
Thread t2 = new Thread(new DoThread());
t1.start();
t2.start();
t1.join();
t2.join();
}
}
so should i be creating an object to store the shared var in and then passing that object to both the DoThread() constructors when creating the threads? I get confused sometimes between when java passes by ref or passes by var, so if i do it this way, will changes to the shared var by t1 be seen by t2?
Well, if you declare a local variable you won't be able to refer to that anywhere other than in classes created within that method.
Where are you implementing Runnable? If it's in the same class, then you could either make it an instance variable and make main set the variable on the same instance that you're creating the thread from, or make it a static variable. If Runnable is implemented in a different class, then when you construct an instance of that class you could give it the data it needs - it's not clear exactly what that means at this point... As others have said, code would be useful. (For example, do the threads need to be able to see changes in the original data?)
As an aside, threading is relatively advanced, whereas propagating data between classes is relatively basic. If you're new to Java, I'd recommend getting started on easier things than threading.
EDIT: For your example, you should use an AtomicInteger, like this:
import java.util.concurrent.atomic.AtomicInteger;
class DoThread implements Runnable {
private final AtomicInteger counter;
DoThread(AtomicInteger counter) {
this.counter = counter;
}
public void run() {
counter.incrementAndGet();
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
AtomicInteger shared = new AtomicInteger(0);
Thread t1 = new Thread(new DoThread(shared));
Thread t2 = new Thread(new DoThread(shared));
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(shared.get()); // Prints 2
}
}
Code would be useful.
If you are using an anonymous class, then you can declare the variables as final and they will be accessible in the anonymous class.
public void main(String[] args) {
final int myvar = 0;
new Thread(new Runnable() {
public void run() {
System.out.println("myvar: "+myvar);
}
}).start();
}
You need to pass a reference to the shared value. If its isn't a reference already you need to change it to an AtomicReference, AtomicInt etc or an array of the value you want to share.
This is the place where PassByRef is more effective. Pass your variable reference to both of runnable instances. Thats all... from then it can be referenced inside your run method.
Ex:
Thread th1 = new Thread (Myrunnable(varRef)). Similarly for other thread

Why do we need a Runnable to start threads?

Why we need to pass the runnable instance while creating the threads using the Runnable interface?
The reason we need to pass the runnable object to the thread object's constructor is that the thread must have some way to get to the run() method we want the thread to execute.
Take an e.g
public class CustomApplet extends Applet {
public void init() {
Runnable ot = new OurClass();
Thread th = new Thread(ot);
th.start();
}
}
Since we are no longer
overriding the run() method of the Thread class, the default run() method of the Thread class is
executed; this default run() method looks like this
public void run() {
if (ot!= null) {
ot.run();
}
}
Hence, ot is the runnable object we passed to the thread's constructor. So the thread begins execution with the run() method of the Thread class, which immediately calls the run() method of our runnable object.
What do you want the new thread to do? You probably want it to execute some code. But what code must it run? You can't just put code in a thread. And Java does not have function pointers. A little trick to solve that problem is to use a object that implements a function. That function is run. So, the object must have a run method. That is what the Runnable interface does, assure it has a run method. Thus, if we give a Runnable object, the thread knows what to do!

Java, alert parent on object change

I have the following setup in Java,
public class Main {
// starts sub class
SubClass sub = new SubClass();
sub.start();
// sub will keep running and call method alert() on a specif change
// method alert is void but updates a public variable named status on sub
while(1==1) {
// I should ideally be able to catch/read sub status result here
// how can I do it?
}
}
I'm new to Java so this may not be valid and my approach may be wrong. That being the case please point me in the right direction.
Thank you.
I presume SubClass.start() starts a new thread so the parent runs in parallel with the child. Then the main class can do a Object.wait() on the sub object, and the SubClass thread can do a Object.notify() on the sub object.
you should start by putting your code into a main method :)
If your SubClass is not already a Runnable,
public class Main
{
public static void main(String args[])
{
Thread myThread = new Thread(new Runnable()
{
public void run()
{
//Instantiate your SubClass here and do stuff. You can pass yourself as a parameter if you plan to do callbacks.
}
});
myThread.setDaemon(true);
myThread.start();
}
}
Alternatively if you've implemented the Runnable interface on SubClass then just use the thread mechanics (wait(), notify(), etc etc).

Categories