创建线程和使用的几种方式

多线程的创建和使用

多线程的创建方式主要两大类,一种是 继承Thread类,另一种是实现Runnab接口。其本质上都是用来创建线程任务,然后启动线程来执行任务。

继承Thread类

继承类Thread是实现线程最简单的一种方式,通过JDK提供的Thread类,我们只需要重写run方法即可。那么当线程启动的时候,就会执行run方法中的内容。

public class MyThread extends Thread{
    @Override
    public void run(){
        while(true) {
            log.info("使用继承Thread类实现多线程场景...");
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}
        log.info("使用继承Thread");
        MyThread myThread1=new MyThread();
        myThread1.start();
        MyThread myThread2=new MyThread();
        myThread2.start();

实现Runnable接口

实现Runnable也是一种创建线程的常见方式,使用接口的方式可以让我们的程序降低耦合度,Runnable接口中仅仅定义了一个方法(run)。

public class MyRunable implements Runnable{
    @Override
    public void run(){
        while(true){
            log.info("实现Runnable来创建线程...");
            try{
                Thread.sleep(1000);
            }catch(Exception e){
                throw new RuntimeException(e);
            }
        }
    }
}
        log.info("实现Runable接口");
        MyRunable myRunable=new MyRunable();
        Thread thread=new Thread(myRunable);
        thread.start();

使用内部类的方式

这并不是一种新的实现线程的方式,只是另外的一种写法。比如有些情况我们的线程就想执行一次,以后就用不到了。那么像上面两种方式(继承Thread类和实现Runnable接口)都还要再定义一个类,显得比较麻烦,我们就可以通过匿名内部类的方式来实现。使用内部类实现依然有两种,分别是继承Thread类和实现Runnable接口。

 log.info("使用内部类");
        Thread thread1=new Thread(){
            @Override
            public void run(){
                while(true){
                    log.info("使用内部类实现多线程(Thread)");
                }
            }
        };
        thread1.start();

        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    log.info("使用内部类实现多线程(Runnable)");
                }
            }
        });
        thread2.start();

定时器

定时器可以说是一种基于线程的一个工具类,还可以定时地来执行某个任务。在java中实现定时任务有跟多种方式,JDK提供了Timer类来帮助开发者创建定时任务,另外也有很多第三方框架提供了对定时任务的支持。

public class TimerSchedule {
    private static final SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    public void runThread() throws ParseException {
        //创建定时器
        Timer timer=new Timer();
        //提交计划任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                log.info("定时任务执行了....");
            }
        },format.parse("2024-3-11 9:00:00"));
    }
}
        TimerSchedule timerSchedule=new TimerSchedule();
        timerSchedule.runThread();

实现Callable接口

不管是继承Thread类还是实现Runnable接口,都存在两个问题,第一个是无法抛出更多的异常,第二个是线程执行完毕之后无法获得线程的返回值。那么实现Callable接口就可以通过泛型参数来指定线程的返回值类型,通过FutureTask的geu方法拿到线程的返回值。
其步骤如下:

  • 创建一个类实现Callable接口,实现Call方法,这个接口类似于Runnable接口,但比Runnable接口更加强大,增加里异常和返回值;
  • 创建一个FutureTask,指定Callable对象,作为线程任务;
  • 创建线程,指定线程任务;
  • 启动线程。
public class MyCallable {
    public void createThread() throws ExecutionException, InterruptedException {
        Callable<Integer> call=()->{
            log.info("线程执行任务开始了...");
            Thread.sleep(2000);
            return 1;
        };
        //将任务封装为FutureTask
        FutureTask<Integer> task=new FutureTask<>(call);

        //开启线程,执行线程任务
        new Thread(task).start();

        //这里实现线程执行之后,结果返回之前
        log.info("线程开始执行,但是还未返回结果");
        Integer result=task.get();
        log.info("主线程执行之后返回的结果为:{}"+result);
    }

}
        //使用Callable创建多线程
        MyCallable myCallable=new MyCallable();
        myCallable.createThread();

基于线程池

线程和数据库连接这些资源都是非常宝贵的资源,如果等每次需要的时候创建,不需要的时候销毁,是非常浪费资源的,那么我们就可以使用缓存的策略,也就是使用线程池。

public class MyThreadPool {
    //创建固定大小的线程池
    public void createThreadPool() {
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        while (true) {
            //提交多个线程任务并执行
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    log.info("通过线程池来执行线程任务");
                }
            });
        }
    }
}
        //使用线程池执行多线程任务
        MyThreadPool myThreadPool=new MyThreadPool();
        myThreadPool.createThreadPool();
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值