Java Threading: How does implementing runnable work for threading

前端 未结 5 1160
Happy的楠姐
Happy的楠姐 2021-02-10 00:21

I understand that if you want to thread you can either extend thread or implement runnable to multithread in java. But why do you have to implement an interface for java to thre

5条回答
  •  醉梦人生
    2021-02-10 00:49

    ExecutorService.submit​( Runnable task )

    You said:

    extend thread

    We no longer need to directly address the Thread class to run code concurrently. Java 5 introduced the Executors framework. See tutorial by Oracle.

    An executor service manages running your tasks on one or more background threads. You can choose from several types of executor services, instantiated via the Executors class.

    For an occasional few short-lived tasks, use an executor service backed by a cached thread pool.

    ExecutorService executorService = Executors.newCachedThreadPool();
    executorService.submit( yourRunnableObjectGoesHere ) ;
    

    The job of an ExecutorService is to execute the code in a method named exactly run or call.

    As other correct Answers explained, the purpose of the Runnable interface is that it represents a contract. When your code claims to implement the Runnable interface, you are promising that your code has a method named exactly run.

    The Java compiler notices this promise and checks to see that the contract is fulfilled. If you pass an object that fails to both (a) declare that it implements Runnable, and (b) carries a method run that takes no arguments and returns no value, then the compiler flags that situation as an error.

    So an executor service requires that you submit your task as an object of a class that implements the Runnable (or Callable) interface to guarantee that when a task arrives to be executed on a background thread, that task has a method named exactly run (or call for Callable).

    Sample code

    Here is some example code. Notice how the executor service does not care what kind object you pass to its submit method. You could pass an object of the class Dog, SalesReport, or Payroll — does not matter. All the executor service cares about is that the object passed to submit has a method called run.

    package work.basil.example;
    
    import java.time.Duration;
    import java.time.Instant;
    import java.util.Objects;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Demo
    {
        public static void main ( String[] args )
        {
            Demo app = new Demo();
            app.demo();
        }
    
        private void demo ( )
        {
            Runnable task = new Runnable()
            {
                @Override
                public void run ( )
                {
                    System.out.println( "Doing this work on a background thread. " + Instant.now() );
                }
            };
    
            ExecutorService executorService = null;
            try
            {
                executorService = Executors.newCachedThreadPool();
                executorService.submit( task );
                executorService.submit( task );
                executorService.submit( task );
    
                // Wait a moment for the background threads to do their work.
                try
                {
                    Thread.sleep( Duration.ofSeconds( 2 ).toMillis() );
                }
                catch ( InterruptedException e )
                {
                    e.printStackTrace();
                }
            }
            finally
            {
                if ( Objects.nonNull( executorService ) ) { executorService.shutdown(); }
                System.out.println( "Ending the main thread. " + Instant.now() );
            }
        }
    }
    

    When run:

    Doing this work on a background thread. 2020-12-20T07:16:26.119414Z
    Doing this work on a background thread. 2020-12-20T07:16:26.119176Z
    Doing this work on a background thread. 2020-12-20T07:16:26.119255Z
    Ending the main thread. 2020-12-20T07:16:28.124384Z
    

    Lambda syntax

    If you are comfortable with lambda syntax in modern Java, we can shorten to a single line that code defining your Runnable implementation. Same effect, just different syntax.

    package work.basil.example;
    
    import java.time.Duration;
    import java.time.Instant;
    import java.util.Objects;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Demo
    {
        public static void main ( String[] args )
        {
            Demo app = new Demo();
            app.demo();
        }
    
        private void demo ( )
        {
            Runnable task = ( ) -> System.out.println( "Doing this work on a background thread. " + Instant.now() );
    
            ExecutorService executorService = null;
            try
            {
                executorService = Executors.newCachedThreadPool();
                executorService.submit( task );
                executorService.submit( task );
                executorService.submit( task );
    
                // Wait a moment for the background threads to do their work.
                try
                {
                    Thread.sleep( Duration.ofSeconds( 2 ).toMillis() );
                }
                catch ( InterruptedException e )
                {
                    e.printStackTrace();
                }
            }
            finally
            {
                if ( Objects.nonNull( executorService ) ) { executorService.shutdown(); }
                System.out.println( "Ending the main thread. " + Instant.now() );
            }
        }
    }
    

    Inheritance

    You asked:

    Does Java's interface extend from something?

    All classes in Java extend either the Object class or some other class that extends from Object.

    An interface in Java does not extend from any class. Remember that an interface is just a contract, a promise that some class may choose to make with regard to having methods with particular names that takes certain types of arguments and return a certain type of value.

    An interface in Java can extend one or more other interfaces. Doing so just adds more methods to the promise being made by a class claiming to implement that interface. Notice that Runnable is extended by two other interfaces: RunnableFuture and RunnableScheduledFuture.

提交回复
热议问题