创建线程的四种方法,以及它们的优缺点

1.用继承Thread类,重写它的run()方法。

在这里插入图片描述
我们可以从图中发现Thread类实现了Runnable接口并且重写了run()方法。而创建线程的第一种方式就是继承Thread类并重写它的run()方法。但是这样做就有缺点,你继承Thread类之后就不能继承其它的类了,不易后期的维护。

我就以计算1-100之内数之和为例:

public class TestThread {
    public static void main(String[] args) {
        new MyThread().start();
    }

}
class MyThread extends  Thread{
    @Override
    public void run() {
        int sum=0;
        for (int i = 1; i <= 100; i++) {
            sum+=i;
        }
        System.out.println("sum="+sum);
    }
}

2.实现Runnable接口,重写run()方法。

这个方法较之前的方法要好一点,但是也有缺点,就是run()方法不能有返回值和抛出异常。

public class TestRunnable {
    public static void main(String[] args) {
        new Thread(new MyRunnable()).start();
    }

}
class MyRunnable implements   Runnable{
    @Override
    public void run() {
        int sum=0;
        for (int i = 1; i <= 100; i++) {
            sum+=i;
        }
        System.out.println("sum="+sum);
    }
}

3.实现Callable接口,重写call()方法。

相较于Runnable接口的方式,方法可以有返回值,并且可以抛出异常。但是此方式需要FutureTask类支持来获取run()方法的返回值。
在这里插入图片描述
从图中我们可以看到,FutureTask类实现了RunnableFuture接口,而RunnableFuture继承了Future接口和Runnable接口。

public class TCallable {
    public static void main(String[] args) {
       MyCallable callable = new MyCallable();
       FutureTask<Integer> futureTask=new FutureTask<>(callable);
       new Thread(futureTask).start();
        try {
        //需要注意的一点是,在得到结果之前,Future接口的get()方法会一直阻塞和ServerSocket类的accept()方法一样
            int sum=futureTask.get();
            System.out.println("sum="+sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }

}
class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum=0;
        for (int i = 1; i <= 100; i++) {
            sum+=i;
        }
        return  sum;
    }
}

4.使用线程池的方式来创建线程。

1.线程池:提供了一个线程队列,队列中保存者所有等待状态的线程, 避免了创建与销毁额外开销,提高了相应速度。
在这里插入图片描述

二、线程池的体系结构:
java.util.concurrent.Executor:负责线程的使用与调度的共接口
|–**ExecutorService 子接口:线程池的主要接口
|–ThreadPoolExecutor 线程池的实现类
|–ScheduleExecutorService 子接口:负责线程的调度
|–ScheduleThreadPoolExecutor:继承ThreadPoolExecutor,
实现ScheduleExecutorService

三、工具类 :Executors
ExecutorService newFixedThreadPool():创建固定大小的线程池
ExecutorService newFixedThreadPool():缓存线程池,线程池的大小数量不固定,可以根据需求自动的更改数量
ExecutorService newSingleThreadExecutor():创建单个线程,线程池中只有一个出现线程
ScheduleExecutorService newScheduleThreadPool():创建固定大小的线程,可以延迟或定时的执行任务

public class TestThreadPool {
    public static void main(String[] args) {
        //1.创建线程池
        ExecutorService pool = Executors.newFixedThreadPool(5);
        MyThreadPool myThreadPool = new MyThreadPool();
        //2.线程池中分配任务
        Future<Integer> future = pool.submit(myThreadPool);
        try {
            int sum=future.get();
            System.out.println("sum="+sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            //3.关闭线程池
            pool.shutdown();
        }
    }
}
class MyThreadPool implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum=0;
        for (int i = 1; i <= 100; i++) {
            sum+=i;
        }
        return  sum;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值