You can define an abstract method to be protected, and hence not part of the public API of the class. However, that seems like an odd design.

Another thing – instance variables. You can have inheritable instance variables in the abstract class.

Abstract class Methods can be defined at various levels down the path.

In a 100% abstract class, you can also define non constant variables that can be herited. It is not possible with interfaces.

The one case where an “100% abstract class” may be advantageous over an interface is in places where API stability is a key concern.

If you write an API where other people are expected to implement your interface you have to stick to the interface. You can’t add any methods to the interface later on because that would break all clients (you would have to work around this by implement a second interface and let your code check againt the usage with instanceof checks and provide an fallback).

Simple Thread implementing Runnable
Counter.java

public class Counter implements Runnable{
    public void run(){
        System.out.println("I am Counter Run Method");
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        Counter objCounter = new Counter();
        Thread objThread = new Thread(objCounter);
        objThread.start();
    }
}
I am Counter Run Method

Main.java(Using Lambda Expression)

public class Main {
    public static void main(String[] args) {
        Thread objThread = new Thread(() -> {
            System.out.println("I am lambda Counter method");
        });

        objThread.start();
    }
}
I am lambda Counter method

new vs runnable vs terminated

  1. When you create thread using new Operator it would be in “new” state
  2. Once you call start method over thread it would Transend to “runnable” state
  3. When run method completed execution it would Transend to “terminated” state

start() vs run()
Thread can be invoked using start or run method. If you use the myThread.start() method it initiates execution of new thread, jvm takes care of execution and scheduling of run method in separate concurrent context. Calling the run method directly myThread.run() will not start a new thread; it will execute the run method in the current thread (ie main thread).

start method of thread class is implemented as when it is called a new Thread is created and code inside run() method is executed in that new Thread. While if run method is executed directly than no new Thread is created and code inside run() will execute on current Thread and no multi-threading will take place

public class Main {
    public static void main(String[] args) {
        Thread objThread = new Thread(() -> {
            System.out.println(Thread.currentThread().getName());
        });

        objThread.start();
    }
}

Output

Thread-0
public class Main {
    public static void main(String[] args) {
        Thread objThread = new Thread(() -> {
            System.out.println(Thread.currentThread().getName());
        });

        objThread.run();
    }
}

Output

main
  1. start() – Initiates the execution of the thread, causing the run method to be called. When you call the start() new thread would spawn and start execution other than main thread

    Task.java

    public class Task implements Runnable{
        @Override
        public void run() {
            System.out.println("Hello from Task.class, executed by " + currentThread().getName() + " thread");
        }
    }
    

    Main.java

    public class Main {
        public static void main(String[] args) {
            Thread thread = new Thread(new Task());
            thread.start();
            thread.run();
        }
    }
    

    Output

    Hello from Task.class, executed by main thread
    Hello from Task.class, executed by Thread-0 thread
    
  2. run() – Contains the code that will be executed by the thread. This method needs to be overridden when extending the Thread class or implementing the Runnable interface. Usage: Defined by the user based on the specific task.
  3. sleep(long milliseconds) – Causes the thread to sleep for the specified number of milliseconds, pausing its execution.
    Thread.sleep(1000);
    
  4. join() Waits for the thread to complete its execution before the current thread continues. It is often used for synchronization between threads.
    myThread.join();
  5. interrupt() Interrupts the thread, causing it to stop or throw an InterruptedException. The thread must handle interruptions appropriately.
    myThread.interrupt();
    
  6. isAlive() Returns true if the thread has been started and has not yet completed its execution, otherwise returns false.
    boolean alive = myThread.isAlive();
    
  7. setName(String name) Sets the name of the thread.
    myThread.setName("MyThread");
    
  8. getName() Returns the name of the thread.
    String threadName = myThread.getName();
    
  9. getName() Returns the name of the thread.
    String threadName = myThread.getName();
    
  10. setPriority(int priority) Sets the priority of the thread. Priorities range from Thread.MIN_PRIORITY to Thread.MAX_PRIORITY.
    myThread.setPriority(Thread.MAX_PRIORITY);
    
  11. getPriority() Returns the priority of the thread.
    int priority = myThread.getPriority();
    
  12. currentThread() Returns a reference to the currently executing thread object.
    Thread currentThread = Thread.currentThread();
    

Thread Implementation Using Runnable Interface

public class Threads2 implements Runnable 
{	
	public static void main(String[] args) 
	{
		Threads2 objThreads2 = new Threads2();
		Thread t1 = new Thread(new Threads2());
		t1.start();
	}
	
	public void run() 
	{	
		System.out.println("Thread Started");
		
		for(int i=0;i<=5;i++)
		{
			System.out.println(i);
			
			try 
			{
			  Thread.sleep(1000);
			}
			catch (InterruptedException e) 
			{
			  e.printStackTrace();
			}
		}
		
		System.out.println("Thread Stopped");
	}
}

There are Four Constructors we can use in Runnable Method of Implementation of Threads.
Thread() – Calls Thread Version of run Method
Thread(Runnable Target)
Thread(Runnable Target, String Name)
Thread(String Name)

If we dont Pass the Instance of Class To thread Constrctor then it will call its own Run Method

Thread t = new Thread(new MyThread());