Java multithreading- 4 ways to create threads in Java

Scenes

The main purpose of this blog is to summarize, so that it can be quickly found at any time when it is needed in work. After all, human memory is limited. Below we quickly summarize the four ways Java implements multi-threaded asynchronous execution of time-consuming code, so that it can be quickly found at any time when it is needed in work.

Refer to related links:
https://www.cnblogs.com/studyjobs/p/15763937.html
https://blog.csdn.net/qq_42764468/article/details/122988589

Implementation method one inherits the Thread class

Continuing with the subclasses of Thread, the methods to be used are introduced:

method name illustrate
void run() After the thread is started, this method will be called and executed, and this method cannot be called directly to achieve multi-threading
void start() Make this method open a new thread and start execution, and the Java virtual machine will automatically call the run method

Implementation steps:

  • Define a class MyThread to inherit the Thread class
  • Override the run() method in the MyThread class
  • Create an object of the MyThread class
  • start thread

Code:

public class MyThread extends Thread {
    
    
    @Override
    public void run() {
    
    

        for(int i=0; i<50; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}

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

        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();

        //这里直接调用 run 方法,并不会开启新线程执行
      	//my1.run();
        //my2.run();

        //必须调用 start 方法,才能开启新线程并自动调用 run 方法
        my1.start();
        my2.start();
    }
}

Implementation method 2. Implement the Runnable interface

Introduction to the Thread construction method that needs to be used:

method name illustrate
Thread(Runnable target) Pass in a class that implements the Runnable interface to construct a Thread object
Thread(Runnable target, String name) Pass in a class that implements the Runnable interface, and construct a Thread object named name

Implementation steps:

  • Define a class MyRunnable to implement the Runnable interface
  • Implement the run() method in the MyRunnable class
  • Create an object of class MyRunnable
  • Create an object of the Thread class and use the MyRunnable object as a parameter of the constructor
  • start thread

Code:

public class MyRunnable implements Runnable {
    
    
    @Override
    public void run() {
    
    

        for(int i=0; i<50; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}

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

        MyRunnable my = new MyRunnable();

        //Thread t1 = new Thread(my);
        //Thread t2 = new Thread(my);

        Thread t1 = new Thread(my,"线程一");
        Thread t2 = new Thread(my,"线程二");

        //启动线程
        t1.start();
        t2.start();
    }
}

Implementation method 3. Implement the Callable interface (with return value)

Introduction to the Thread construction method that needs to be used:

method name illustrate
V call() This is the method to be implemented in the Callable interface, which is equivalent to the run method in the Runnable interface
FutureTask(Callable callable) Use the Callable interface implementation class instance to create a FutureTask, which will call the call method in the Callable interface when it runs
V get() The get method of the FutureTask instance can block the code from continuing to execute until the return result in the asynchronous thread is obtained

Implementation steps:

  • Define a class MyCallable to implement the Callable interface
  • Reimplement the call() method in the MyCallable class
  • Create an object of class MyCallable
  • Create a FutureTask object and use the MyCallable object as a parameter of the constructor
  • Create an object of the Thread class and use the FutureTask object as a parameter of the constructor
  • start thread
  • If you want to get the return value, you can call the get method to get the result after the thread ends

Code:

//因为这里想返回 String 值,所以实现 String 类型的 Callable 接口
public class MyCallable implements Callable<String> {
    
    
    @Override
    public String call() throws Exception {
    
    

        for (int i = 0; i < 100; i++) {
    
    
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }

        //这里返回一个字符串
        return "这是我返回的字符串结果";
    }
}

public class CallableDemo {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    

        MyCallable mc = new MyCallable();

        //因为 MyCallable 实现了 String 类型的 Callable 接口
        //所以返回值也是 String 类型,所以创建的是 String 类型的 FutureTask 对象
        FutureTask<String> ft = new FutureTask<>(mc);

        //传入 FutureTask 实例,创建线程对象
        Thread t1 = new Thread(ft);

        //不能在这个地方使用 FutureTask 的 get 方法获取异步线程的返回值,否则程序将卡死在这里。
        //因为 t1 线程还没有执行,所以无法获取到返回值,所以如果执行 get 方法,程序将卡死在这里。
        //String s = ft.get();

        //开启新线程,异步执行 MyCallable 实例中的 call 方法逻辑
        t1.start();

        //这里编写一些实现其它业务逻辑代码进行执行
        //可以做一些其它比较耗时的任务
        //......

        //获取异步线程的返回值
        String s = ft.get();
        System.out.println(s);
    }
}

Implementation method 4. Use thread pool

Be aware of the following when using different thread types

  • Runnbale type: threadpool.execute
  • Callable type: threadpool.submit

future.get() : This method is unique to the Callable type; it will get the return value after the thread is executed.
Using future.get() will block the Callable type thread, although it will not block the Runnbale type thread, but More or less will affect the blocking of the entire thread pool implementation method.

related code

public class RunnableTaskDemo implements Runnable {
    
    
    @Override
    public void run() {
    
    
        for(int i=0;i<3;i++){
    
    
            System.out.println(Thread.currentThread().getName()+" 轮次:"+i);

            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

public class CreateDemo {
    
    
    //创建有3个线程的线程池
    private static ExecutorService threadpool = Executors.newFixedThreadPool(3);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        // 1、执行Runnbale类型的target目标实例,无返回
        threadpool.execute(new RunnableTaskDemo());

        //2、 执行Runnbale类型的target目标实例,无返回,(内部类形式写法)
        threadpool.execute(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                for(int i=0;i<3;i++){
    
    
                    System.out.println(Thread.currentThread().getName()+" 轮次:"+i);
                    
                    try {
    
    
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }       
        });

        // 3、提交Callable执行目标实例,有返回
        Future future = threadpool.submit(new CallableTaskDemo());
        System.out.println("异步执行的结果为:" + future.get());
    }
}


Guess you like

Origin blog.csdn.net/qq_20236937/article/details/128860641