"Hello, Amigo! Ellie told you about threads, and I'm going to tell you how you work with them. To create a new thread, you need to:"

1) Create a Thread object

2) Pass it the method you want to run

3) Call the start method on the created Thread object.

Consider this example:

Code Description
class Printer implements Runnable
{
public void run()
{
System.out.println("I’m printer");
}
}
Class that implements the Runnable interface.
public static void main(String[] args)
{
Printer printer = new Printer();
Thread childThread = new Thread(printer);
childThread.start();
}
1 Create an instance of the Printer class, which implements the run method.
2 Create a new Thread object. We pass the constructor the printer object, whose run() method needs to be invoked.
3 Start the new thread by calling the start() method.

Small Java programs usually consist of one thread called the «main thread». But programs more often launch additional threads, which are called «child threads». The main thread runs the main method and ends. The run method of the Runnable is the analogous method for child threads.

"Ah, lots of threads means lots of main methods."

Creating and starting new threads - 1

To tell a Thread object which specific method it should start, we need to somehow pass a method to it. In Java, this is done using the Runnable interface. This interface contains a single abstract method: void run(). The Thread class has a Thread(Runnable Runnable) constructor. You can pass in any object that implements the Runnable interface.

Your class must inherit Runnable and override its run method. Invoking this method is what starts the new thread. You can write whatever you want in the run method.

Code Description
class Printer implements Runnable
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
Class that implements the Runnable interface.
public static void main(String[] args)
{
Printer printer1 = new Printer("Nick");
Thread thread1 = new Thread(printer1);
thread1.start();

Printer printer2 = new Printer("Jack");
Thread thread2 = new Thread(printer2);
thread2.start();
}
Create two threads, each of which will be based on its own Printer object.
public static void main(String[] args)
{
Printer printer = new Printer("Natasha");

Thread thread1 = new Thread(printer);
thread1.start();

Thread thread2 = new Thread(printer);
thread2.start();

Thread thread3 = new Thread(printer);
thread3.start();
}
Create three threads based on a single Printer object.

What's more, you can combine this all into one class. The Thread class inherits the Runnable interface, so you only need to override its run method:

Another way to create a new thread
class Printer extends Thread
{
private String name;
public Printer(String name)
{
this.name = name;
}
public void run()
{
System.out.println("I’m " + this.name);
}
}
Inherit the Thread class, which implements the Runnable interface, and then override the run method.
public static void main(String[] args)
{
Printer printer = new Printer("Jack");
printer.start();

Printer printer2 = new Printer("Jack");
printer2.start();

}
Create two threads, each of which will be based on its own Printer object.

"This is a more elegant solution."

"Yes, but it has its shortcomings:"

1) You may need to start several threads based on a single object, as in the example with Natasha.

2) If you inherit from the Thread class, you can't add another parent class to your class.

3) If your class has a parent class, you can't add Thread as a second parent class.

"In other words, after the start method is called, each of the threads starts executing the run method of the object passed to the constructor?"

"Yes. If nothing is passed to the constructor, then Thread just executes its internal run method."

"But why don't we just call the method like this?"

Code
public static void main(String[] args)
{
 Printer printer1 = new Printer("Nick");
 printer1.run();
}

"When the main thread reaches the run method, its "little robot" simply goes inside and executes all the commands inside it. Only after they are executed will it return to the main method and continue the execute further commands. Thus, no second "little robot" will be created. All the work will be performed sequentially, not in parallel (simultaneously)."

"I see. Can you call some other method, something other than run?"

"No. It's all tied to the Runnable interface, which only "knows" about one of its methods: run()."