java线程创建的方式及其优缺点

Java创建的方式

Java创建线程的方式有三种:

  1. 继承Thread类。
  2. 实现Runnable接口,并作为参数传递给Thread对象。
  3. 实现Callable接口,作为参数传递给FutureTask,将FutureTask对象传递给Thread对象,并可获取到线程的返回值。
//通过继承Thread的方式,创建Java线程
public class ThreadTask extends Thread {
	//接收外部传递进来的参数
	private String param;
    @Override
    public void run() {
        System.out.println("I am thread");
        System.out.println("外部参数"+param);
    }
    public static void main(String[] args) {
        ThreadTask t1 = new ThreadTask();
        t1.start();
    }
    
    //接收外部传递进来的参数
	public void setParam(String param){
		this.param = param;
	}
}

//通过实现Runnable接口的方式,创建Java线程
public class RunableTask implements Runnable{
    @Override
    public void run() {
        System.out.println("I am runable");
    }
    public static void main(String[] args) {
        RunableTask runableTask = new RunableTask();
        Thread t1 = new Thread(runableTask);
        t1.start();
    }
}

//通过实现Runnable接口的方式,创建Java线程
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class CallableTask implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "I am Callable";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask = new FutureTask<>(new CallableTask());
        Thread t1 = new Thread(futureTask);
        t1.start();
        //获取线程的返回值
        String res = futureTask.get();
        System.out.println(res);
    }
}

线程创建方式的优缺点

  1. 继承Thread类的优缺点:

优点:
1:可以在run里直接使用this对象表示当前线程对象,无需使用Thread.currentThread();
2:我们可以根据特殊的需求,可以在子类里创建成员变量,通过set方法或者构造函数接收外部传递进来的参数。
缺点:
1:Java不支持多线程,如果继承了Thread类,就不能在继承其他类。
2:任务与代码没有分离,当多个线程执行一样的任务时,需求多分任务代码,导致代码量重复。Runnable则没有这个限制。
3:任务没有返回值。

  1. 实现Runnable接口的优缺点

优点:
1:多个线程可以共用同一个run方法的代码。
缺点:
1:和继承Thread方式一样,任务没有返回值。
2:线程不支持set方法和构造函数传参,只能使用主线程里被声明为final的变量。在Runnable接口里设置变量,将是线程的共享变量,不属于线程私有变量。

  1. 实现Callable接口的优缺点

优点:可以拿到任务的返回结果。
缺点:线程不支持set方法和构造函数传参,只能使用主线程里被声明为final的变量。

开发中请根据他们的优缺点,选择线程创建的方式。

创建线程主要有以下四种方式及其优缺点: ### 继承Thread类 - **实现方式**:创建一个类继承`Thread`类,并重写`run()`方法,在`run()`方法中定义线程要执行的任务。 ```java class MyThread extends Thread { @Override public void run() { System.out.println("Thread is running"); } } public class Main { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); } } ``` - **优点**:编写简单,如果需要访问当前线程,无需使用`Thread.currentThread()`方法,直接使用`this`即可获得当前线程[^2]。 - **缺点**:因为线程类已经继承了`Thread`类,所以不能再继承其他的父类,这在需要多重继承的场景下会受到限制[^2]。 ### 实现Runnable接口 - **实现方式**:创建一个类实现`Runnable`接口,实现`run()`方法,然后将该类的实例作为参数传递给`Thread`类的构造函数来创建线程。 ```java class MyRunnable implements Runnable { @Override public void run() { System.out.println("Runnable thread is running"); } } public class Main { public static void main(String[] args) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } } ``` - **优点**:可以避免单继承的局限性,一个类在实现`Runnable`接口的同时还可以继承其他类;适合多个线程共享同一个资源的情况,将任务线程分离,提高了代码的可维护性可扩展性。 - **缺点**:不能直接获取线程执行的返回值。 ### 使用CallableFuture接口 - **实现方式**:创建一个类实现`Callable`接口,实现`call()`方法,该方法有返回值。使用`ExecutorService`来提交`Callable`任务,并通过`Future`对象获取线程执行的结果。 ```java import java.util.concurrent.*; class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { return 1 + 2; } } public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executor = Executors.newSingleThreadExecutor(); MyCallable callable = new MyCallable(); Future<Integer> future = executor.submit(callable); Integer result = future.get(); System.out.println("Result: " + result); executor.shutdown(); } } ``` - **优点**:可以获取线程执行的返回值,适用于需要获取线程执行结果的场景。 - **缺点**:代码相对复杂,需要使用`ExecutorService``Future`等类来管理获取结果。 ### 使用线程池 - **实现方式**:通过`Executors`工具类创建不同类型的线程池,如`newFixedThreadPool`、`newCachedThreadPool`等,然后将实现了`Runnable`或`Callable`接口的任务提交给线程池执行。 ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class MyTask implements Runnable { @Override public void run() { System.out.println("Task is running in thread pool"); } } public class Main { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(2); MyTask task = new MyTask(); executor.submit(task); executor.shutdown(); } } ``` - **优点**:可以提高性能,避免频繁地创建销毁线程带来的开销;可以对线程进行统一的管理监控,如设置线程的最大数量、线程的存活时间等;可以提高系统的稳定性,防止因创建过多线程导致系统资源耗尽。 - **缺点**:线程池的配置管理相对复杂,如果配置不当可能会导致性能问题或资源浪费。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值