java四种创建线程的方法

java中创建线程的四种方法

  • 继承Thread类
  • 实现Runnable接口
  • 实现Callable接口
  • 使用线程池

1.继承Thread类

/**
    继承Thread类,java只能继承一个类,不够灵活
 */
public class MyThread extends Thread{

    public void run(){
        System.out.println("run方法执行了......");
    }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
        System.out.println(myThread.getName()+"启动了...");

    }
}

2.实现Runnable接口


public class MyRunnable implements Runnable {

    public void run() {
        System.out.println("run方法执行了......");
    }

    public static void main(String[] args) {

        Thread myThread = new Thread(new MyRunnable());
        myThread.start();
        System.out.println(myThread.getName()+"启动了......");
        
    }
}

3.实现Callable接口

实现Callable接口,和Runnable类似,重写call方法,允许返回值,可以抛异常
自定义类,实现Callable接口,自定义泛型“Callable”,就是call方法返回的类型


public class MyCallable implements Callable<String> {

    public String call() throws Exception {

        System.out.println("call方法执行了......");
        return "success";
    }

    public static void main(String[] args) {
        //FutureTask的泛型要和MyCallable call方法返回的类型一致
        FutureTask<String> task = new FutureTask<String>(new MyCallable());
        Thread thread = new Thread(task);
        thread.start();
        System.out.println(thread.getName()+"启动了......");


        //打印返回结果
        try {
            String result = task.get();
            System.out.println("MyCallable返回结果:"+result);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(task.isDone());

    }
}

4.使用线程池

线程池对象获取线程并执行Runnable实例

public class MyRunnable implements Runnable {

    public void run() {
        System.out.println("run方法执行了......");
    }

    public static void main(String[] args) {

        //使用线程池创建线程
        //1.使用Executors获取线程池对象
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //2.通过线程池对象获取线程并执行MyRunnable实例
        executorService.execute(new MyRunnable());
        
    }
}

线程池对象获取线程并执行Callable实例

public class MyCallable implements Callable<String> {

    public String call() throws Exception {

        System.out.println("call方法执行了......");
        return "success";
    }

    public static void main(String[] args) {
       	ExecutorService executorService = Executors.newFixedThreadPool(10);
        FutureTask<String> task = new FutureTask<String>(new MyCallable());
        executorService.execute(task);

    }
}

5. 总结

1. 实现接口和继承Thread类比较

  • 接口更适合多个相同的程序的代码的线程去共享同一资源
  • 接口可以避免java中的单继承局限性
  • 接口代码可以被多个线程共享,代码和线程独立
  • 线程池只能放入实现Runnable或Callable接口的线程,不能直接放入继承Thread的类
  • 扩充:在java中,每个线程运行至少启动2个线程。一个是main线程,一个是垃圾收集器线程

2.Runnable和Callable接口比较

  • 相同点:

    两者都是接口
    两者都可以来编写多线程程序
    两者都需要调用Thread.start()启动线程

  • 不同点:

    实现Callable接口的线程能返回执行结果;而实现Runnable接口的线程不能返回结果
    Callable接口的Call()方法允许抛出异常;而Runnable接口的run()方法不允许抛异常
    实现Callable接口的线程可以调用Future.cancel取消执行,而实现Runnable接口的线程不能
    注意点:Callable接口支持返回执行结果,此时需要调用FutureTask.get方法实现,此方法会阻塞
    主线程直到获取"将来"结果;当不调用此方法时,主线程不会阻塞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值