线程的创建方式

谈谈线程创建有哪些方式

  • 1 继承Thread类重写run方法,然后调用自定义实例的start方法。
  • 2 实现Runable接口重写run方法,将Runable实例封装为Thread实例并调用start方法。
  • 3 实现Callable接口重写call方法,将Callable实例封装为FutureTask对象,进而封装为Thread对象并调用start方法。可以通过FutureTask对象get方法获取线程返回值。
  • 4 使用线程池
  • 方法1有单继承的局限性,自定义类继承了Thread不能继承其他类了。
  • 方法2解决了单继承的局限性,而且将任务和线程分开了,一个Runable对象表示一个任务,可以将一个任务封装为多个线程,并且多个线程共享当前任务对象数据。
  • 方法3支持线程有返回结果,运行Callable任务可以得到一个future对象,表示异步计算结果。

使用Thread类创建线程

  • 自定义线程类继承Thread类,覆写run方法,通过调用子线程对象的start方法启动多线程。
  • 实例
public class Test {
public static final Logger log = LoggerFactory.getLogger(Test.class);
public static void main(String[] args) {
           Thread thread1 = new Thread(){
                   @Override
                   public void run() {
                           for(int i=0;i<10;i++){
                                   Test.log.info("i="+i);
                           }
                   }
           };
           thread1.start();
        }
}

Runable结合Thread创建线程

  • 将线程与可运行的任务分开。Runable实例对象表示任务,Thread对象表示线程。
  • 首先实例化一个实现Runable接口的对象创建一个任务,然后实例化Thread对象将任务封装为线程,最后调用start方法进行执行。
  • 示例
public class Test {
public static final Logger log = LoggerFactory.getLogger(Test.class);
public static void main(String[] args) {
           Job job1 = new Job();
           Thread thread1 = new Thread(job1,"子线程1");
           thread1.start();
 }
}

class Job implements Runnable{
        @Override
        public void run() {
                for(int i=0;i<10;i++){
                        Test.log.info("i="+i);
                }
        }
}
  • 使用lambda简化代码
public class Test {
public static final Logger log = LoggerFactory.getLogger(Test.class);
public static void main(String[] args) {
           Runnable r = ()->{
                   for(int i=0;i<10;i++){
                           Test.log.info("i="+i);
                   }
           };
           new Thread(r,"子线程1").start();
 }
}
  • 一个runable对象也可以同时包装为多个线程对象,这样多个线程就会共享runable对象的数据。
  • 在实例化Thread对象时可以传入一个Runable对象,当传入Runable对象后会将该对象作为Thread类的成员,在调用Thread对象的start方法时,会进行判断,如果当前Thread对象有Runable对象成员就执行Runable对象的run方法,否则就执行自己的run方法。

使用FutureTask创建线程

  • Runable方法创建的线程是没有返回值的,使用FutureTask支持线程有返回值,可以在一个线程中获取另一个线程的返回结果。
  • FutureTask类间接实现了Runable接口和Future接口,Future接口支持获取线程结果,Runable接口支持我们可以将当前对象封装为任务对象。
  • 实现方式:传入一个callable对象,实例化FutureTask对象。然后将FutureTask对象包装为Thread线程对象,调用start方法执行。
  • 示例
//创建 callable 对象
Callable<String> callable = new Callable<String>() {
    @Override
    public String call() throws Exception {
        System.out.println(1);
        System.out.println(2);
        System.out.println(3);
        return "hello"; //线程返回值
    }
};
//包装 futureTask对象
FutureTask<String> futureTask = new FutureTask<>(callable);
Thread t = new Thread(futureTask);
t.start();
System.out.println(futureTask.get()); //获取线程返回结果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值