Java多线程的三种用法和比较

Java的三种多线程用法分别为:继承Thread、实现Runnable、实现Callable,下面会分别进行介绍

第一种继承Thread

这种方法很简单,就是继承Thread,然后重写run方法,在调用的时候用start方法就行了。
Thread类中已经实现了Runnable,使用起来相对来说更方便简洁。

//直接继承Thread,然后重写run方法
public class MyThread extends Thread{

    @Override
    public void run(){
        System.out.println("Thread");
    }
}
class Test{
    public static void main(String[]args){
        //1、初始化一个对象后,调用的是start方法,不是调用重写的run方法
        MyThread myThread=new MyThread();
        myThread.start();
    }
}

第二种实现Runnable

这种方式就是直接实现Runnable,在调用的时候最终还是把Runnable传到Thread再调用Thread的start实现

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable");
    }
}
class Test{
    public static void main(String[]args){
        //2、使用Runnable实现
        Runnable runnable=new MyRunnable();
        Thread thread=new Thread(runnable);
        thread.start();
    }
}

第三种实现Callable

使用这种方式的好处就是能得到线程的返回值和抛出的异常,这是前面两种所不具备的

class MyCallable implements Callable{

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName());
        return 1;
    }
}
class Test{
    public static void main(String[]args){
        //3、使用callable实现,使用callable的好处是有返回值
        //new Thread(new FutureTask<Integer>(new MyCallable())).start();
        Callable callable=new MyCallable();
        int sumNumber=0;
        for (int i=1 ;i<=10;i++) {
            FutureTask<Integer> futureTask = new FutureTask(callable);
            Thread thread1 = new Thread(futureTask, "callable"+i);
            thread1.start();

            try {
                //得到返回值,这里会造成阻塞,意思是直到这个线程工作完后,才能进行下一步
                Integer result = futureTask.get();
                sumNumber+=result;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        //所有线程完后计算的结果
        System.out.println(sumNumber);

    }
}

三种方式的对比

第一种方式内部已经实现了Runnable,所以相对于其它两种使用起来更方便,但是因为Java的单继承属性,所以我们的类继承Thread后就不能继承其它类了

java 多线程中的变量 java 多线程调用一个方法_ide


第二种方式的好处就是我们的类实现的是一个接口,所以还可以继承其它类

第三种方式相对来说比较复杂,但是它的好处就是能得到线程的返回值和抛出的异常,如果不需要得到返回值和抛出的异常,建议不使用这种方式,因为在调用futureTask.get(),也就是得到线程的返回值时是阻塞的,只有等这个线程执行完,才能执行接下来的事情

三种方式的实现和结果

package com.zhou.thread.multithread;

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

/**
 * @author zhou
 * @version 1.0
 * @Description
 * @date 2022/3/25 10:58
 */

//直接继承Thread,然后重写run方法
public class MyThread extends Thread{

    @Override
    public void run(){
        System.out.println("Thread");
    }
}
class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("Runnable");
    }
}

class MyCallable implements Callable{

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName());
        return 1;
    }
}
class Test{
    public static void main(String[]args){

        //1、初始化一个对象后,调用的是start方法,不是调用重写的run方法
        MyThread myThread=new MyThread();
        myThread.start();

        //2、使用Runnable实现
        Runnable runnable=new MyRunnable();
        Thread thread=new Thread(runnable);
        thread.start();

        //3、使用callable实现,使用callable的好处是有返回值
        //new Thread(new FutureTask<Integer>(new MyCallable())).start();
        Callable callable=new MyCallable();
        int sumNumber=0;
        for (int i=1 ;i<=10;i++) {
            FutureTask<Integer> futureTask = new FutureTask(callable);
            Thread thread1 = new Thread(futureTask, "callable"+i);
            thread1.start();

            try {
                //得到返回值,这里会造成阻塞,意思是直到这个线程工作完后,才能进行下一步
                Integer result = futureTask.get();
                sumNumber+=result;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        //所有线程完后计算的结果
        System.out.println(sumNumber);

    }
}

结果

java 多线程中的变量 java 多线程调用一个方法_java 多线程中的变量_02