"Java Multithreading interview questions" series - and the difference between the three methods to create a thread

1. Create a thread and the difference between the three methods

1.1 Thread class inheritance

First, define Thread subclasses and override the run () method:

package com.zwwhnly.springbootaction.javabase.thread;

public class MyFirstThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.printf("[MyFirstThread]输出:%d,当前线程名称:%s\n",
                    i, getName());
        }
    }
}

Then, create an instance of the subclass and call the start () method to start the thread:

package com.zwwhnly.springbootaction.javabase.thread;

public class ThreadTest {
    public static void main(String[] args) {
        System.out.println("主线程开始执行,当前线程名称:" +
                Thread.currentThread().getName());

        Thread firstThread = new MyFirstThread();
        firstThread.start();

        System.out.println("主线程执行结束,当前线程名称:" +
                Thread.currentThread().getName());
    }
}

Run results are shown below:

The main thread begins execution, the name of the current thread: main

The main thread execution ends, the name of the current thread: main

[MyFirstThread] output: 0, the name of the current thread: Thread-0

[MyFirstThread] Output: 1, the current thread name: Thread-0

[MyFirstThread] Output: 2, the current thread name: Thread-0

[MyFirstThread] Output: 3, the current thread name: Thread-0

[MyFirstThread] Output: 4, the current thread name: Thread-0

The results can be seen running from the following two questions:

  1. There are two program threads, each main thread and main thread custom Thread-0.
  2. Calls firstThread.start();, run () method body code is not executed immediately, but executed asynchronously.

View source Thread class, you can find the Thread class implements the interface Runnable:

public class Thread implements Runnable {
    // 省略其它代码
}

Here is the key, the interview often ask!

1.2 implement Runnable (recommended)

First, implement class and implements Runnable interface run () method:

package com.zwwhnly.springbootaction.javabase.thread;

public class MySecondThread implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.printf("[MySecondThread]输出:%d,当前线程名称:%s\n",
                    i, Thread.currentThread().getName());
        }
    }
}

Then call the Thread class constructor creates Thread instance and call the start () method to start the thread:

package com.zwwhnly.springbootaction.javabase.thread;

public class ThreadTest {
    public static void main(String[] args) {
        Runnable target = new MySecondThread();
        Thread secondThread = new Thread(target);
        secondThread.start();
    }
}

Run results are shown below:

The main thread begins execution, the name of the current thread: main

The main thread execution ends, the name of the current thread: main

[MySecondThread] output: 0, the name of the current thread: Thread-0

[MySecondThread] Output: 1, the current thread name: Thread-0

[MySecondThread] Output: 2, the current thread name: Thread-0

[MySecondThread] Output: 3, the current thread name: Thread-0

[MySecondThread] Output: 4, the current thread name: Thread-0

As can be seen, the use of the results of running this way and inheritance Thread class is the same.

1.3 implement Callable Interface

First, Callable implement class interface and implements call () method:

package com.zwwhnly.springbootaction.javabase.thread;

import java.util.Random;
import java.util.concurrent.Callable;

public class MyThirdThread implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        Thread.sleep(6 * 1000);
        return new Random().nextInt();
    }
}

Then, call the constructor FutureTask class is created FutureTask instance:

Callable<Integer> callable = new MyThirdThread();
FutureTask<Integer> futureTask = new FutureTask<>(callable);

Finally, call the Thread class constructor creates Thread instance and call the start () method to start the thread:

package com.zwwhnly.springbootaction.javabase.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThreadTest {
    public static void main(String[] args) {
        System.out.println("主线程开始执行,当前线程名称:" +
                Thread.currentThread().getName());

        Callable<Integer> callable = new MyThirdThread();
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        new Thread(futureTask).start();

        try {
            System.out.println("futureTask.isDone() return:" + futureTask.isDone());

            System.out.println(futureTask.get());

            System.out.println("futureTask.isDone() return:" + futureTask.isDone());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("主线程执行结束,当前线程名称:" +
                Thread.currentThread().getName());
    }
}

Run results are shown below:

The main thread begins execution, the name of the current thread: main

futureTask.isDone() return:false

-1193053528

futureTask.isDone() return:true

The main thread execution ends, the name of the current thread: main

Can be found using the Callable interfaces in this way, we can futureTask.get()get the results of the implementation of threads, and two kinds of ways before, is no return value.

Note: Calling futureTask.get()execution result acquisition thread, the main thread will block until the results obtained.

Blocking results as shown below:

1.4 difference

Below are the highlights, interviews often ask!

  1. Java, the class supports only single inheritance, if a class inherits from the Thread class, you can not inherit other classes, so if a class only inherit other classes, they must create a thread, you can use to achieve Runable interface the way.
  2. It creates a way to achieve Runable interface thread can handle the same resources, sharing of resources.
  3. Thread creation that implement Callable interface way, can get to the return value of the thread execution, whether complete information.

About point 2, it can be understood by the following example.

If we have a total of 10 tickets (shared resources), in order to enhance the efficiency of ticket sales, opened three threads to sell, the code is as follows:

package com.zwwhnly.springbootaction.javabase.thread;

public class SaleTicketThread implements Runnable {
    private int quantity = 10;

    @Override
    public void run() {
        while (quantity > 0) {
            System.out.println(quantity-- + " is saled by " +
                    Thread.currentThread().getName());
        }
    }
}
public static void main(String[] args) {
    Runnable runnable = new SaleTicketThread();
    Thread saleTicketThread1 = new Thread(runnable);
    Thread saleTicketThread2 = new Thread(runnable);
    Thread saleTicketThread3 = new Thread(runnable);

    saleTicketThread1.start();
    saleTicketThread2.start();
    saleTicketThread3.start();
}

Because the three threads are performed asynchronously, so each operating results may be different, different times of 2 listed below operating results.

1st Run Results:

10 is saled by Thread-0

8 is saled by Thread-0

7 is saled by Thread-0

5 is saled by Thread-0

9 is saled by Thread-1

3 is saled by Thread-1

2 is saled by Thread-1

1 is saled by Thread-1

4 is saled by Thread-0

6 is saled by Thread-2

The second run results:

10 is saled by Thread-0

9 is saled by Thread-0

8 is saled by Thread-0

7 is saled by Thread-0

6 is saled by Thread-0

5 is saled by Thread-0

3 is saled by Thread-0

2 is saled by Thread-0

4 is saled by Thread-2

1 is saled by Thread-1

If the above SaleTicketThread modified to inherit the Thread class way, it becomes a three threads each have 10 votes, that becomes 30 votes, rather than the three threads share 10 votes.

2. Thread class distinction start () and run () of

2.1 Example

Because we realize the benefits of the Runnable interface, and virtually all use of multithreading is that way, so we defined earlier MyFirstThread also be modified to implement Runnable way:

package com.zwwhnly.springbootaction.javabase.thread;

public class MyFirstThread implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.printf("[MyFirstThread]输出:%d,当前线程名称:%s\n",
                    i, Thread.currentThread().getName());
        }
    }
}

Then the continued use of previously defined MyFirstThread, MySecondThread, we look at the next start () call results:

package com.zwwhnly.springbootaction.javabase.thread;

public class ThreadTest {
    public static void main(String[] args) {

        System.out.println("主线程开始执行,当前线程名称:" +
                Thread.currentThread().getName());

        Thread firstThread = new Thread(new MyFirstThread());

        Runnable target = new MySecondThread();
        Thread secondThread = new Thread(target);

        firstThread.start();
        secondThread.start();

        System.out.println("主线程执行结束,当前线程名称:" +
                Thread.currentThread().getName());
    }
}

Operating results (Note: multiple runs, the result may be different):

The main thread begins execution, the name of the current thread: main

[MyFirstThread] output: 0, the name of the current thread: Thread-0

[MyFirstThread] Output: 1, the current thread name: Thread-0

[MySecondThread] Output: 0, the current thread name: Thread-1

The main thread execution ends, the name of the current thread: main

[MySecondThread] output: 1, the name of the current thread: Thread-1

[MySecondThread] Output: 2, the current thread name: Thread-1

[MySecondThread] Output: 3, the current thread name: Thread-1

[MySecondThread] Output: 4, the current thread name: Thread-1

[MyFirstThread] Output: 2, the current thread name: Thread-0

[MyFirstThread] Output: 3, the current thread name: Thread-0

[MyFirstThread] Output: 4, the current thread name: Thread-0

As can be seen, the calls start () method, the program has three threads, each thread based main, Thread-0, Thread-1, and the order of execution is not executed sequentially, there is uncertainty.

Then start () method modified to run () method, as follows:

firstThread.run();
secondThread.run();

At this time, operating results are as follows (multiple runs, the result is the same):

The main thread begins execution, the name of the current thread: main

[MyFirstThread] output: 0, the name of the current thread: main

[MyFirstThread] output: 1, the name of the current thread: main

[MyFirstThread] output: 2, the name of the current thread: main

[MyFirstThread] Output: 3, the name of the current thread: main

[MyFirstThread] Output: 4, the name of the current thread: main

[MySecondThread] output: 0, the name of the current thread: main

[MySecondThread] output: 1, the name of the current thread: main

[MySecondThread] output: 2, the name of the current thread: main

[MySecondThread] Output: 3, the name of the current thread: main

[MySecondThread] Output: 4, the name of the current thread: main

The main thread execution ends, the name of the current thread: main

As can be seen, after the call run () method, a program, only the main thread, the two threads custom does not start, and the execution order is executed sequentially.

1.2 summary

Below are the highlights, interviews often ask!

  • run () method is just an ordinary method, then the caller waits run () method is finished, so is the serial execution, rather than parallel execution.
  • start () method will start a thread after thread gets CPU resources will be performed automatically run (the contents of the method body), true concurrent execution.

3. Runnable and Callable difference of

In the previous article sections (1.2 and 1.3 to achieve Runnable interface to achieve Callable Interface), we learned how to create use Runnable, Callable Interface thread, and now we look separately defined Runable and Callable interface, which is defined as follows Runable interface below:

public interface Runnable {
    public abstract void run();
}

Callable interface is defined as follows:

public interface Callable<V> {
    V call() throws Exception;
}

It can be seen, the difference between Runnable and Callable the following main points:

  1. Runable execution method is run (), is performed Callable method call ()
  2. call () method can throw an exception, run () method if an exception can only digest inside
  3. Implement Runnable thread does not return a value, implement Callable interface thread can return the results
  4. Implement Callable interface thread, can be used with FutureTask, get the thread is completed, the thread is canceled, the thread execution results, you can cancel the thread of execution.

4. The reference source and

Source Address: https://github.com/zwwhnly/springboot-action.git , welcome to download.

Java, to achieve the distinction between two ways multithreading

The difference between Java Thread run () and start () of

Java Runnable and Callable difference

Callable, Runnable compare and usage

Runnable and Callable differences and usage

If you feel well written, I welcome attention to the micro-channel public number: "Shanghai Stranger" all blog gets updated.

If you are interested, you can also add my micro letter: zwwhnly_002, technology exchange and discuss together.

Guess you like

Origin www.cnblogs.com/zwwhnly/p/11890032.html